From 258b200cc24ff3424baae924e54f81d81814a3a6 Mon Sep 17 00:00:00 2001 From: kruland2607 Date: Wed, 18 Apr 2012 17:43:09 +0000 Subject: [PATCH] Made the ComponentPresetChooserDialog much more cool by reworking the table. User can hide and unhide columns, reorder columns, and change units by using a right click context menu in the header bar. git-svn-id: https://openrocket.svn.sourceforge.net/svnroot/openrocket/trunk@565 180e2498-e6e9-4542-8430-84ac67f01cd8 --- core/resources/l10n/messages.properties | 3 + .../preset/ComponentPresetChooserDialog.java | 65 +---- .../dialogs/preset/ComponentPresetTable.java | 253 ++++++++++++++++++ .../preset/ComponentPresetTableColumn.java | 83 ++++++ .../gui/dialogs/preset/XTableColumnModel.java | 241 +++++++++++++++++ .../sf/openrocket/preset/ComponentPreset.java | 21 ++ 6 files changed, 606 insertions(+), 60 deletions(-) create mode 100644 core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java create mode 100644 core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java create mode 100644 core/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java diff --git a/core/resources/l10n/messages.properties b/core/resources/l10n/messages.properties index 43c4beae..bb61f70e 100644 --- a/core/resources/l10n/messages.properties +++ b/core/resources/l10n/messages.properties @@ -1593,6 +1593,9 @@ ComponentPresetChooserDialog.title = Choose component preset ComponentPresetChooserDialog.filter.label = Filter: ComponentPresetChooserDialog.checkbox.filterAftDiameter = Match aft diameter ComponentPresetChooserDialog.checkbox.filterForeDiameter = Match fore diameter +ComponentPresetChooserDialog.menu.sortAsc = Sort Ascending +ComponentPresetChooserDialog.menu.sortDesc = Sort Descending +ComponentPresetChooserDialog.menu.units = Units table.column.Favorite = Favorite table.column.Manufacturer = Manufacturer table.column.PartNo = Part Number diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java index c2a6ccb0..4c967a92 100644 --- a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java +++ b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetChooserDialog.java @@ -8,6 +8,7 @@ import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import javax.swing.JButton; @@ -44,8 +45,8 @@ public class ComponentPresetChooserDialog extends JDialog { private final RocketComponent component; - private final JTable componentSelectionTable; - private final TableRowSorter sorter; + private ComponentPresetTable componentSelectionTable; +// private final JTable componentSelectionTable; private final JTextField filterText; private final JCheckBox foreDiameterFilterCheckBox; private final JCheckBox aftDiameterFilterCheckBox; @@ -70,29 +71,6 @@ public class ComponentPresetChooserDialog extends JDialog { presets = Application.getComponentPresetDao().listForType(component.getPresetType()); - /* - * Set up the Column Table model - */ - final Column[] columns = new Column[columnKeys.length+1]; - - columns[0] = new Column(trans.get("table.column.Favorite") ) { - @Override - public Object getValueAt(int row) { - return Boolean.valueOf(ComponentPresetChooserDialog.this.presets.get(row).isFavorite()); - } - - @Override - public void setValueAt(int row, Object value) { - Application.getComponentPresetDao().setFavorite(ComponentPresetChooserDialog.this.presets.get(row), (Boolean) value); - } - - @Override - public Class getColumnClass() { - return Boolean.class; - } - - }; - for (int i = 0; i < columnKeys.length; i++) { final TypedKey key = columnKeys[i]; if ( key == ComponentPreset.OUTER_DIAMETER ) { @@ -103,21 +81,6 @@ public class ComponentPresetChooserDialog extends JDialog { // magic +1 is because we have inserted the column for favorites above. foreDiameterColumnIndex = i+1; } - columns[i+1] = new Column(trans.get("table.column." + key.getName())) { - @Override - public Object getValueAt(int row) { - ComponentPreset preset = ComponentPresetChooserDialog.this.presets.get(row); - if ( ! preset.has(key) ) { - return null; - } - Object value = preset.get(key); - if (key.getType() == Double.class && key.getUnitGroup() != null) { - return new Value( (Double) value, key.getUnitGroup() ); - } else { - return value; - } - } - }; } /* @@ -132,20 +95,6 @@ public class ComponentPresetChooserDialog extends JDialog { foreDiameterColumnIndex = aftDiameterColumnIndex; } - ColumnTableModel tableModel = new ColumnTableModel(columns) { - @Override - public int getRowCount() { - return ComponentPresetChooserDialog.this.presets.size(); - } - - @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return columnIndex == 0; - } - - }; - - /* * Add filter by text. */ @@ -205,12 +154,8 @@ public class ComponentPresetChooserDialog extends JDialog { aftDiameterFilterCheckBox.setVisible(false); } - componentSelectionTable = new JTable( tableModel ); + componentSelectionTable = new ComponentPresetTable( presets, Arrays.>asList(columnKeys) ); - componentSelectionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - - sorter = new TableRowSorter(tableModel); - componentSelectionTable.setRowSorter(sorter); JScrollPane scrollpane = new JScrollPane(); scrollpane.setViewportView(componentSelectionTable); @@ -319,6 +264,6 @@ public class ComponentPresetChooserDialog extends JDialog { } } - sorter.setRowFilter( RowFilter.andFilter(filters) ); + componentSelectionTable.setRowFilter( RowFilter.andFilter(filters) ); } } diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java new file mode 100644 index 00000000..9f319fdc --- /dev/null +++ b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTable.java @@ -0,0 +1,253 @@ +package net.sf.openrocket.gui.dialogs.preset; + +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.RowFilter; +import javax.swing.RowSorter.SortKey; +import javax.swing.SortOrder; +import javax.swing.event.ListSelectionEvent; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; +import javax.swing.table.TableColumn; +import javax.swing.table.TableModel; +import javax.swing.table.TableRowSorter; + +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.preset.ComponentPreset; +import net.sf.openrocket.preset.TypedKey; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.Unit; +import net.sf.openrocket.unit.UnitGroup; + +public class ComponentPresetTable extends JTable { + + private static final Translator trans = Application.getTranslator(); + + private final TableRowSorter sorter; + private final List presets; + private final AbstractTableModel tableModel; + private final XTableColumnModel tableColumnModel; + private final ComponentPresetTableColumn[] columns; + + public ComponentPresetTable(List presets, List> visibleColumnKeys) { + super(); + this.presets = presets; + this.columns = new ComponentPresetTableColumn[ComponentPreset.orderedKeyList.size()+1]; + + tableColumnModel = new XTableColumnModel(); + + /* + * Set up the Column Table model + */ + columns[0] = new ComponentPresetTableColumn.Favorite(0); + tableColumnModel.addColumn(columns[0]); + + List hiddenColumns = new ArrayList(); + { + int index = 1; + for (final TypedKey key: ComponentPreset.orderedKeyList ) { + if ( key.getType() == Double.class && key.getUnitGroup() != null ) { + columns[index] = new ComponentPresetTableColumn.DoubleWithUnit((TypedKey)key,index); + } else { + columns[index] = new ComponentPresetTableColumn.Parameter(key,index); + } + tableColumnModel.addColumn(columns[index]); + if ( visibleColumnKeys.indexOf(key) < 0 ) { + hiddenColumns.add(columns[index]); + } + index ++; + } + } + + + tableModel = new AbstractTableModel() { + final ComponentPresetTableColumn[] myColumns = columns; + @Override + public int getRowCount() { + return ComponentPresetTable.this.presets.size(); + } + + @Override + public int getColumnCount() { + return myColumns.length; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return myColumns[columnIndex].getValueFromPreset(ComponentPresetTable.this.presets.get(rowIndex)); + } + + @Override + public void setValueAt(Object aValue, int rowIndex, int columnIndex) { + // Only support favorite + if ( columnIndex != 0 ) { + return; + } + ComponentPreset preset = ComponentPresetTable.this.presets.get(rowIndex); + Application.getComponentPresetDao().setFavorite(preset, (Boolean) aValue); + } + + @Override + public boolean isCellEditable(int rowIndex, int columnIndex) { + return columnIndex == 0; + } + + @Override + public Class getColumnClass(int columnIndex) { + return columnIndex == 0 ? Boolean.class : Object.class; + } + + }; + + this.setAutoCreateColumnsFromModel(false); + this.setColumnModel( tableColumnModel ); + this.setModel(tableModel); + this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + for ( TableColumn hiddenColumn : hiddenColumns ) { + tableColumnModel.setColumnVisible(hiddenColumn, false); + } + + sorter = new TableRowSorter(tableModel); + this.setRowSorter(sorter); + + JTableHeader header = this.getTableHeader(); + + header.setReorderingAllowed(true); + + header.addMouseListener( new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + if ( e.isPopupTrigger() ) { + doPopup(e); + } + } + @Override + public void mouseReleased(MouseEvent e) { + if ( e.isPopupTrigger() ) { + doPopup(e); + } + } + }); + } + + public void setRowFilter( RowFilter filter ) { + sorter.setRowFilter( filter ); + } + + private void doPopup(MouseEvent evt ) { + + // Figure out what column header was clicked on. + int colIndex = tableColumnModel.getColumnIndexAtX( evt.getX() ); + ComponentPresetTableColumn colClicked = null; + if ( colIndex >=0 ) { + colClicked = (ComponentPresetTableColumn) tableColumnModel.getColumn(colIndex); + } + + JPopupMenu columnMenu = new ColumnPopupMenu(colClicked, colIndex); + columnMenu.show(evt.getComponent(),evt.getX(),evt.getY()); + } + + private class ColumnPopupMenu extends JPopupMenu { + + ColumnPopupMenu(ComponentPresetTableColumn colClicked, int colClickedIndex) { + if ( colClickedIndex >= 0 ) { + JCheckBoxMenuItem item = new SortAscColumnMenuItem(colClickedIndex); + this.add(item); + item = new SortDescColumnMenuItem(colClickedIndex); + this.add(item); + this.addSeparator(); + if ( colClicked instanceof ComponentPresetTableColumn.DoubleWithUnit ) { + this.add( new UnitSelectorMenuItem( (ComponentPresetTableColumn.DoubleWithUnit) colClicked )); + this.addSeparator(); + } + } + for( TableColumn c: columns ) { + JCheckBoxMenuItem item = new ToggleColumnMenuItem(c); + this.add(item); + } + } + + + private class SortAscColumnMenuItem extends JCheckBoxMenuItem implements ItemListener { + private int columnClicked; + SortAscColumnMenuItem(int columnClicked) { + super( trans.get("ComponentPresetChooserDialog.menu.sortAsc") ); + this.addItemListener(this); + this.columnClicked = columnClicked; + } + @Override + public void itemStateChanged(ItemEvent e) { + sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.ASCENDING))); + } + } + + private class SortDescColumnMenuItem extends JCheckBoxMenuItem implements ItemListener { + private int columnClicked; + SortDescColumnMenuItem(int columnClicked) { + super( trans.get("ComponentPresetChooserDialog.menu.sortDesc") ); + this.addItemListener(this); + this.columnClicked = columnClicked; + } + @Override + public void itemStateChanged(ItemEvent e) { + sorter.setSortKeys( Collections.singletonList( new SortKey(columnClicked, SortOrder.DESCENDING))); + } + } + + private class ToggleColumnMenuItem extends JCheckBoxMenuItem implements ItemListener { + TableColumn col; + ToggleColumnMenuItem( TableColumn col ) { + super( String.valueOf(col.getHeaderValue()), tableColumnModel.isColumnVisible(col)); + this.addItemListener(this); + this.col = col; + } + @Override + public void itemStateChanged(ItemEvent e) { + tableColumnModel.setColumnVisible(col, !tableColumnModel.isColumnVisible(col)); + } + } + + private class UnitSelectorMenuItem extends JMenu implements ItemListener { + ComponentPresetTableColumn.DoubleWithUnit col; + UnitSelectorMenuItem( ComponentPresetTableColumn.DoubleWithUnit col ) { + super(trans.get("ComponentPresetChooserDialog.menu.units")); + this.col = col; + UnitGroup group = col.unitGroup; + Unit selectedUnit = col.selectedUnit; + for( Unit u : group.getUnits() ) { + JCheckBoxMenuItem item = new JCheckBoxMenuItem( u.toString() ); + if ( u == selectedUnit ) { + item.setSelected(true); + } + item.addItemListener(this); + this.add(item); + } + + } + @Override + public void itemStateChanged(ItemEvent e) { + JCheckBoxMenuItem item = (JCheckBoxMenuItem) e.getItem(); + String val = item.getText(); + col.selectedUnit = col.unitGroup.findApproximate(val); + ComponentPresetTable.this.tableModel.fireTableDataChanged(); + return; + } + + } + + } +} diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java new file mode 100644 index 00000000..70878f5a --- /dev/null +++ b/core/src/net/sf/openrocket/gui/dialogs/preset/ComponentPresetTableColumn.java @@ -0,0 +1,83 @@ +package net.sf.openrocket.gui.dialogs.preset; + +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableColumn; + +import net.sf.openrocket.l10n.Translator; +import net.sf.openrocket.preset.ComponentPreset; +import net.sf.openrocket.preset.TypedKey; +import net.sf.openrocket.startup.Application; +import net.sf.openrocket.unit.Unit; +import net.sf.openrocket.unit.UnitGroup; +import net.sf.openrocket.unit.Value; + +public abstract class ComponentPresetTableColumn extends TableColumn { + + private static final Translator trans = Application.getTranslator(); + + protected ComponentPresetTableColumn( String header, int modelIndex ) { + this.setHeaderValue(header); + this.setModelIndex(modelIndex); + + } + + public abstract Object getValueFromPreset( ComponentPreset preset ); + + public static class Favorite extends ComponentPresetTableColumn { + + public Favorite(int modelIndex) { + super(trans.get("table.column.Favorite"), modelIndex); + } + + @Override + public Object getValueFromPreset( ComponentPreset preset ) { + return Boolean.valueOf(preset.isFavorite()); + } + + } + + public static class Parameter extends ComponentPresetTableColumn { + + protected final TypedKey key; + + public Parameter( TypedKey key, int modelIndex ) { + super( trans.get("table.column." + key.getName()), modelIndex ); + this.key = key; + } + + @Override + public Object getValueFromPreset(ComponentPreset preset) { + return preset.has(key) ? preset.get(key) : null; + } + + } + + + public static class DoubleWithUnit extends Parameter { + + UnitGroup unitGroup; + Unit selectedUnit; + + public DoubleWithUnit( TypedKey key, int modelIndex ) { + super(key,modelIndex); + this.unitGroup = key.getUnitGroup(); + this.selectedUnit = unitGroup.getDefaultUnit(); + } + + @Override + public Object getValueFromPreset(ComponentPreset preset) { + Double value = (Double) super.getValueFromPreset(preset); + if ( value != null ) { + return new Value((Double)super.getValueFromPreset(preset),selectedUnit); + } else { + return null; + } + } + + + } + +} + + + diff --git a/core/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java b/core/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java new file mode 100644 index 00000000..9968e247 --- /dev/null +++ b/core/src/net/sf/openrocket/gui/dialogs/preset/XTableColumnModel.java @@ -0,0 +1,241 @@ +package net.sf.openrocket.gui.dialogs.preset; + +import java.util.Enumeration; +import java.util.Vector; + +import javax.swing.table.DefaultTableColumnModel; +import javax.swing.table.TableColumn; + +public class XTableColumnModel extends DefaultTableColumnModel { + + /** Array of TableColumn objects in this model. + * Holds all column objects, regardless of their visibility + */ + protected Vector allTableColumns = new Vector(); + + /** + * Creates an extended table column model. + */ + XTableColumnModel() { + super(); + } + + /** + * Sets the visibility of the specified TableColumn. + * The call is ignored if the TableColumn is not found in this column model + * or its visibility status did not change. + *

+ * + * @param aColumn the column to show/hide + * @param visible its new visibility status + */ + // listeners will receive columnAdded()/columnRemoved() event + public void setColumnVisible(TableColumn column, boolean visible) { + if(!visible) { + super.removeColumn(column); + } + else { + // find the visible index of the column: + // iterate through both collections of visible and all columns, counting + // visible columns up to the one that's about to be shown again + int noVisibleColumns = tableColumns.size(); + int noInvisibleColumns = allTableColumns.size(); + int visibleIndex = 0; + + for(int invisibleIndex = 0; invisibleIndex < noInvisibleColumns; ++invisibleIndex) { + TableColumn visibleColumn = (visibleIndex < noVisibleColumns ? (TableColumn)tableColumns.get(visibleIndex) : null); + TableColumn testColumn = (TableColumn)allTableColumns.get(invisibleIndex); + + if(testColumn == column) { + if(visibleColumn != column) { + super.addColumn(column); + super.moveColumn(tableColumns.size() - 1, visibleIndex); + } + return; // #################### + } + if(testColumn == visibleColumn) { + ++visibleIndex; + } + } + } + } + + /** + * Makes all columns in this model visible + */ + public void setAllColumnsVisible(boolean visible) { + int noColumns = allTableColumns.size(); + + for(int columnIndex = 0; columnIndex < noColumns; ++columnIndex) { + TableColumn visibleColumn = (columnIndex < tableColumns.size() ? (TableColumn)tableColumns.get(columnIndex) : null); + TableColumn invisibleColumn = (TableColumn)allTableColumns.get(columnIndex); + if ( visible ) { + + if(visibleColumn != invisibleColumn) { + super.addColumn(invisibleColumn); + super.moveColumn(tableColumns.size() - 1, columnIndex); + } + } else { + super.removeColumn(invisibleColumn); + } + } + } + + /** + * Maps the index of the column in the table model at + * modelColumnIndex to the TableColumn object. + * There may me multiple TableColumn objects showing the same model column, though this is uncommon. + * This method will always return the first visible or else the first invisible column with the specified index. + * @param modelColumnIndex index of column in table model + * @return table column object or null if no such column in this column model + */ + public TableColumn getColumnByModelIndex(int modelColumnIndex) { + for (int columnIndex = 0; columnIndex < allTableColumns.size(); ++columnIndex) { + TableColumn column = (TableColumn)allTableColumns.get(columnIndex); + if(column.getModelIndex() == modelColumnIndex) { + return column; + } + } + return null; + } + + /** Checks wether the specified column is currently visible. + * @param aColumn column to check + * @return visibility of specified column (false if there is no such column at all. [It's not visible, right?]) + */ + public boolean isColumnVisible(TableColumn aColumn) { + return (tableColumns.indexOf(aColumn) >= 0); + } + + /** Append column to the right of exisiting columns. + * Posts columnAdded event. + * @param column The column to be added + * @see #removeColumn + * @exception IllegalArgumentException if column is null + */ + @Override + public void addColumn(TableColumn column) { + allTableColumns.add(column); + super.addColumn(column); + } + + /** Removes column from this column model. + * Posts columnRemoved event. + * Will do nothing if the column is not in this model. + * @param column the column to be added + * @see #addColumn + */ + @Override + public void removeColumn(TableColumn column) { + int allColumnsIndex = allTableColumns.indexOf(column); + if(allColumnsIndex != -1) { + allTableColumns.remove(allColumnsIndex); + } + super.removeColumn(column); + } + + /** Moves the column from oldIndex to newIndex. + * Posts columnMoved event. + * Will not move any columns if oldIndex equals newIndex. + * + * @param oldIndex index of column to be moved + * @param newIndex new index of the column + * @exception IllegalArgumentException if either oldIndex or + * newIndex + * are not in [0, getColumnCount() - 1] + */ + @Override + public void moveColumn(int oldIndex, int newIndex) { + if ((oldIndex < 0) || (oldIndex >= getColumnCount()) || + (newIndex < 0) || (newIndex >= getColumnCount())) + throw new IllegalArgumentException("moveColumn() - Index out of range"); + + TableColumn fromColumn = (TableColumn) tableColumns.get(oldIndex); + TableColumn toColumn = (TableColumn) tableColumns.get(newIndex); + + int allColumnsOldIndex = allTableColumns.indexOf(fromColumn); + int allColumnsNewIndex = allTableColumns.indexOf(toColumn); + + if(oldIndex != newIndex) { + allTableColumns.remove(allColumnsOldIndex); + allTableColumns.add(allColumnsNewIndex, fromColumn); + } + + super.moveColumn(oldIndex, newIndex); + } + + /** + * Returns the total number of columns in this model. + * + * @param onlyVisible if set only visible columns will be counted + * @return the number of columns in the tableColumns array + * @see #getColumns + */ + public int getColumnCount(boolean onlyVisible) { + Vector columns = (onlyVisible ? tableColumns : allTableColumns); + return columns.size(); + } + + /** + * Returns an Enumeration of all the columns in the model. + * + * @param onlyVisible if set all invisible columns will be missing from the enumeration. + * @return an Enumeration of the columns in the model + */ + public Enumeration getColumns(boolean onlyVisible) { + Vector columns = (onlyVisible ? tableColumns : allTableColumns); + + return columns.elements(); + } + + /** + * Returns the position of the first column whose identifier equals identifier. + * Position is the the index in all visible columns if onlyVisible is true or + * else the index in all columns. + * + * @param identifier the identifier object to search for + * @param onlyVisible if set searches only visible columns + * + * @return the index of the first column whose identifier + * equals identifier + * + * @exception IllegalArgumentException if identifier + * is null, or if no + * TableColumn has this + * identifier + * @see #getColumn + */ + public int getColumnIndex(Object identifier, boolean onlyVisible) { + if (identifier == null) { + throw new IllegalArgumentException("Identifier is null"); + } + + Vector columns = (onlyVisible ? tableColumns : allTableColumns); + int noColumns = columns.size(); + TableColumn column; + + for(int columnIndex = 0; columnIndex < noColumns; ++columnIndex) { + column = (TableColumn)columns.get(columnIndex); + + if(identifier.equals(column.getIdentifier())) + return columnIndex; + } + + throw new IllegalArgumentException("Identifier not found"); + } + + /** + * Returns the TableColumn object for the column + * at columnIndex. + * + * @param columnIndex the index of the column desired + * @param onlyVisible if set columnIndex is meant to be relative to all visible columns only + * else it is the index in all columns + * + * @return the TableColumn object for the column + * at columnIndex + */ + public TableColumn getColumn(int columnIndex, boolean onlyVisible) { + return (TableColumn)tableColumns.elementAt(columnIndex); + } +} diff --git a/core/src/net/sf/openrocket/preset/ComponentPreset.java b/core/src/net/sf/openrocket/preset/ComponentPreset.java index 410470e7..5c42e7bd 100644 --- a/core/src/net/sf/openrocket/preset/ComponentPreset.java +++ b/core/src/net/sf/openrocket/preset/ComponentPreset.java @@ -4,6 +4,7 @@ import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.security.MessageDigest; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; @@ -148,6 +149,26 @@ public class ComponentPreset implements Comparable { keyMap.put(MASS.getName(), MASS); } + public final static List> orderedKeyList = Arrays.>asList( + MANUFACTURER, + PARTNO, + DESCRIPTION, + OUTER_DIAMETER, + INNER_DIAMETER, + LENGTH, + SHOULDER_DIAMETER, + SHOULDER_LENGTH, + FORE_SHOULDER_DIAMETER, + FORE_SHOULDER_LENGTH, + SHAPE, + THICKNESS, + FILLED, + MASS, + FINISH, + MATERIAL + ); + + // package scope constructor to encourage use of factory. ComponentPreset() { } -- 2.47.2