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
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;
private final RocketComponent component;
- private final JTable componentSelectionTable;
- private final TableRowSorter<TableModel> sorter;
+ private ComponentPresetTable componentSelectionTable;
+// private final JTable componentSelectionTable;
private final JTextField filterText;
private final JCheckBox foreDiameterFilterCheckBox;
private final JCheckBox aftDiameterFilterCheckBox;
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 ) {
// 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;
- }
- }
- };
}
/*
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.
*/
aftDiameterFilterCheckBox.setVisible(false);
}
- componentSelectionTable = new JTable( tableModel );
+ componentSelectionTable = new ComponentPresetTable( presets, Arrays.<TypedKey<?>>asList(columnKeys) );
- componentSelectionTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-
- sorter = new TableRowSorter<TableModel>(tableModel);
- componentSelectionTable.setRowSorter(sorter);
JScrollPane scrollpane = new JScrollPane();
scrollpane.setViewportView(componentSelectionTable);
}
}
- sorter.setRowFilter( RowFilter.andFilter(filters) );
+ componentSelectionTable.setRowFilter( RowFilter.andFilter(filters) );
}
}
--- /dev/null
+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<TableModel> sorter;
+ private final List<ComponentPreset> presets;
+ private final AbstractTableModel tableModel;
+ private final XTableColumnModel tableColumnModel;
+ private final ComponentPresetTableColumn[] columns;
+
+ public ComponentPresetTable(List<ComponentPreset> presets, List<TypedKey<?>> 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<TableColumn> hiddenColumns = new ArrayList<TableColumn>();
+ {
+ int index = 1;
+ for (final TypedKey<?> key: ComponentPreset.orderedKeyList ) {
+ if ( key.getType() == Double.class && key.getUnitGroup() != null ) {
+ columns[index] = new ComponentPresetTableColumn.DoubleWithUnit((TypedKey<Double>)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>(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<? super TableModel ,? super Integer> 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;
+ }
+
+ }
+
+ }
+}
--- /dev/null
+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<Double> 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;
+ }
+ }
+
+
+ }
+
+}
+
+
+
--- /dev/null
+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<TableColumn> allTableColumns = new Vector<TableColumn>();
+
+ /**
+ * 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.
+ * <p>
+ *
+ * @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
+ * <code>modelColumnIndex</code> 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 <code>column</code> to the right of exisiting columns.
+ * Posts <code>columnAdded</code> event.
+ * @param column The column to be added
+ * @see #removeColumn
+ * @exception IllegalArgumentException if <code>column</code> is <code>null</code>
+ */
+ @Override
+ public void addColumn(TableColumn column) {
+ allTableColumns.add(column);
+ super.addColumn(column);
+ }
+
+ /** Removes <code>column</code> from this column model.
+ * Posts <code>columnRemoved</code> 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 <code>oldIndex</code> to <code>newIndex</code>.
+ * Posts <code>columnMoved</code> event.
+ * Will not move any columns if <code>oldIndex</code> equals <code>newIndex</code>.
+ *
+ * @param oldIndex index of column to be moved
+ * @param newIndex new index of the column
+ * @exception IllegalArgumentException if either <code>oldIndex</code> or
+ * <code>newIndex</code>
+ * 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 <code>tableColumns</code> array
+ * @see #getColumns
+ */
+ public int getColumnCount(boolean onlyVisible) {
+ Vector<TableColumn> columns = (onlyVisible ? tableColumns : allTableColumns);
+ return columns.size();
+ }
+
+ /**
+ * Returns an <code>Enumeration</code> of all the columns in the model.
+ *
+ * @param onlyVisible if set all invisible columns will be missing from the enumeration.
+ * @return an <code>Enumeration</code> of the columns in the model
+ */
+ public Enumeration<TableColumn> getColumns(boolean onlyVisible) {
+ Vector<TableColumn> columns = (onlyVisible ? tableColumns : allTableColumns);
+
+ return columns.elements();
+ }
+
+ /**
+ * Returns the position of the first column whose identifier equals <code>identifier</code>.
+ * Position is the the index in all visible columns if <code>onlyVisible</code> 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 <code>identifier</code>
+ *
+ * @exception IllegalArgumentException if <code>identifier</code>
+ * is <code>null</code>, or if no
+ * <code>TableColumn</code> has this
+ * <code>identifier</code>
+ * @see #getColumn
+ */
+ public int getColumnIndex(Object identifier, boolean onlyVisible) {
+ if (identifier == null) {
+ throw new IllegalArgumentException("Identifier is null");
+ }
+
+ Vector<TableColumn> 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 <code>TableColumn</code> object for the column
+ * at <code>columnIndex</code>.
+ *
+ * @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 <code>TableColumn</code> object for the column
+ * at <code>columnIndex</code>
+ */
+ public TableColumn getColumn(int columnIndex, boolean onlyVisible) {
+ return (TableColumn)tableColumns.elementAt(columnIndex);
+ }
+}
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;
keyMap.put(MASS.getName(), MASS);
}
+ public final static List<TypedKey<?>> orderedKeyList = Arrays.<TypedKey<?>>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() {
}