Updates and fixed to preset handling

This commit is contained in:
Sampo Niskanen 2012-04-01 19:16:25 +00:00
parent 6f465cd0a2
commit 70e7936454
12 changed files with 227 additions and 259 deletions

View File

@ -1,4 +1,4 @@
Manufacturer,PartNo,id(cm),od(cm),maxlength(cm) Manufacturer,PartNo,InnerDiameter,OuterDiameter,Length
Semroc,BT-3,0.8865,0.9525,45.72 Semroc,BT-3,0.8865,0.9525,45.72
Semroc,BT-3H,0.8865,0.9525,7.62 Semroc,BT-3H,0.8865,0.9525,7.62
Semroc,BT-3XW,0.8865,0.9525,3.81 Semroc,BT-3XW,0.8865,0.9525,3.81

1 Manufacturer PartNo id(cm) InnerDiameter od(cm) OuterDiameter maxlength(cm) Length
2 Semroc BT-3 0.8865 0.9525 45.72
3 Semroc BT-3H 0.8865 0.9525 7.62
4 Semroc BT-3XW 0.8865 0.9525 3.81

View File

@ -1587,3 +1587,7 @@ CustomFinImport.error.title = Error loading fin profile
CustomFinImport.error.badimage = Could not deduce fin shape from image. CustomFinImport.error.badimage = Could not deduce fin shape from image.
CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin. CustomFinImport.description = The image will be converted internally to black and white image (black for the fin), so make sure you use a solid dark color for the fin, and white or a light color for the background. The fin must be touching the bottom of the image, which is the base of the fin.
PresetModel.lbl.select = Select preset:
PresetModel.lbl.database = From database...

View File

@ -8,26 +8,25 @@ import java.util.List;
import net.sf.openrocket.preset.ComponentPreset; import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.TypedKey; import net.sf.openrocket.preset.TypedKey;
import net.sf.openrocket.rocketcomponent.BodyTube;
import au.com.bytecode.opencsv.CSVReader; import au.com.bytecode.opencsv.CSVReader;
public class PresetCSVReader { public class PresetCSVReader {
private InputStream is; private InputStream is;
private ColumnDefinition[] columns; private ColumnDefinition[] columns;
public PresetCSVReader( InputStream is ) { public PresetCSVReader(InputStream is) {
this.is = is; this.is = is;
} }
public List<ComponentPreset> parse() throws IOException { public List<ComponentPreset> parse() throws IOException {
List<ComponentPreset> templates = new ArrayList<ComponentPreset>(); List<ComponentPreset> templates = new ArrayList<ComponentPreset>();
InputStreamReader r = new InputStreamReader(is); InputStreamReader r = new InputStreamReader(is);
// Create the CSV reader. Use comma separator and double-quote escaping. // Create the CSV reader. Use comma separator and double-quote escaping.
CSVReader reader = new CSVReader(r,',','"'); CSVReader reader = new CSVReader(r, ',', '"');
String[] headers = reader.readNext(); String[] headers = reader.readNext();
if (headers == null || headers.length == 0) { if (headers == null || headers.length == 0) {
@ -35,28 +34,28 @@ public class PresetCSVReader {
} }
columns = new ColumnDefinition[headers.length]; columns = new ColumnDefinition[headers.length];
for( int i = 0; i< headers.length; i++ ) { for (int i = 0; i < headers.length; i++) {
String h = headers[i]; String h = headers[i];
if( "Manufacturer".equals(h) ) { if ("Manufacturer".equals(h)) {
columns[i] = new ColumnDefinition.Manufactuer(); columns[i] = new ColumnDefinition.Manufactuer();
} else if ( "PartNumber".equals(h) ) { } else if ("PartNo".equals(h)) {
columns[i] = new ColumnDefinition.PartNumber(); columns[i] = new ColumnDefinition.PartNumber();
} else if ( "Type".equals(h) ) { } else if ("Type".equals(h)) {
columns[i] = new ColumnDefinition.Type(); columns[i] = new ColumnDefinition.Type();
} else { } else {
TypedKey key = ComponentPreset.keyMap.get(h); TypedKey key = ComponentPreset.keyMap.get(h);
if ( key == null ) { if (key == null) {
throw new RuntimeException("Invalid parameter key " + h + " in file"); throw new RuntimeException("Invalid parameter key " + h + " in file");
} }
columns[i] = new ColumnDefinition.Parameter( key ); columns[i] = new ColumnDefinition.Parameter(key);
} }
} }
String[] line; String[] line;
while( (line = reader.readNext()) != null ) { while ((line = reader.readNext()) != null) {
ComponentPreset preset = new ComponentPreset(); ComponentPreset preset = new ComponentPreset();
for( int i = 0; i< headers.length; i++ ) { for (int i = 0; i < headers.length; i++) {
if ( i > line.length ) { if (i > line.length) {
break; break;
} }
String value = line[i]; String value = line[i];
@ -64,7 +63,7 @@ public class PresetCSVReader {
} }
templates.add(preset); templates.add(preset);
} }
return templates; return templates;
} }

View File

@ -1,97 +0,0 @@
package net.sf.openrocket.gui.adaptors;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
public class BodyTubePresetModel extends AbstractListModel implements ComboBoxModel {
private final RocketComponent component;
private List<ComponentPreset> presets;
public BodyTubePresetModel(RocketComponent component) {
presets = Application.getDaos().getBodyTubePresetDao().listAll();
this.component = component;
}
public static class BodyTubePresetAdapter {
// If the ComponentPreset bt is null, then no preset is selected.
private ComponentPreset bt;
private BodyTubePresetAdapter( ComponentPreset bt ) {
this.bt = bt;
}
@Override
public String toString() {
if ( bt != null ) {
return bt.getManufacturer() + " " + bt.getPartNo();
} else {
return "";
}
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((bt == null) ? 0 : bt.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
// I don't know why the default equals generated by Eclipse does not work.
// instead of relying on bt.equals(other.bt), we have to compare the hashcodes of those objects.
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BodyTubePresetAdapter other = (BodyTubePresetAdapter) obj;
if (bt == null) {
if (other.bt != null)
return false;
} else if (other.bt == null)
return false;
return bt.hashCode() == other.bt.hashCode();
}
}
@Override
public int getSize() {
return presets.size();
}
@Override
public Object getElementAt(int index) {
if ( index < 0 ) {
return null;
}
return new BodyTubePresetAdapter(presets.get(index));
}
@Override
public void setSelectedItem(Object anItem) {
BodyTubePresetAdapter selected = (BodyTubePresetAdapter) anItem;
if ( selected == null ) {
component.loadPreset(null);
} else {
component.loadPreset(selected.bt);
}
}
@Override
public Object getSelectedItem() {
ComponentPreset preset = (ComponentPreset) component.getPresetComponent();
if ( preset == null ) {
return null;
} else {
return new BodyTubePresetAdapter(preset);
}
}
}

View File

@ -0,0 +1,93 @@
package net.sf.openrocket.gui.adaptors;
import java.util.List;
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
public class PresetModel extends AbstractListModel implements ComboBoxModel, ComponentChangeListener {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
private static final String SELECT_PRESET = trans.get("lbl.select");
private static final String SELECT_DATABASE = trans.get("lbl.database");
private final RocketComponent component;
private ComponentPreset previousPreset;
private final List<ComponentPreset> presets;
public PresetModel(RocketComponent component) {
// FIXME: Make generic for any component type
// FIXME: This should load only the user's favorites, NOT all presets
presets = Application.getDaos().getBodyTubePresetDao().listAll();
this.component = component;
previousPreset = component.getPresetComponent();
component.addComponentChangeListener(this);
}
@Override
public int getSize() {
return presets.size() + 2;
}
@Override
public Object getElementAt(int index) {
if (index == 0) {
return SELECT_PRESET;
}
if (index == getSize() - 1) {
return SELECT_DATABASE;
}
return presets.get(index - 1);
}
@Override
public void setSelectedItem(Object item) {
log.user("User selected preset item '" + item + "' for component " + component);
System.err.println("**** Setting item: " + item);
if (item == null) {
// FIXME: What to do?
} else if (item.equals(SELECT_PRESET)) {
component.clearPreset();
} else if (item.equals(SELECT_DATABASE)) {
// FIXME: Open database dialog
} else {
// FIXME: Add undo point here
component.loadPreset((ComponentPreset) item);
}
}
@Override
public Object getSelectedItem() {
ComponentPreset preset = component.getPresetComponent();
if (preset == null) {
return SELECT_PRESET;
} else {
return preset;
}
}
@Override
public void componentChanged(ComponentChangeEvent e) {
if (previousPreset != component.getPresetComponent()) {
previousPreset = component.getPresetComponent();
System.err.println("Firing event");
fireContentsChanged(this, 0, getSize());
}
}
// FIXME: Make model invalidatable
}

View File

@ -1,138 +1,120 @@
package net.sf.openrocket.gui.configdialog; package net.sf.openrocket.gui.configdialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox; import javax.swing.JCheckBox;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout; import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument; import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor; import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BodyTubePresetModel;
import net.sf.openrocket.gui.adaptors.BooleanModel; import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.gui.adaptors.DoubleModel; import net.sf.openrocket.gui.adaptors.DoubleModel;
import net.sf.openrocket.gui.adaptors.PresetModel;
import net.sf.openrocket.gui.components.BasicSlider; import net.sf.openrocket.gui.components.BasicSlider;
import net.sf.openrocket.gui.components.UnitSelector; import net.sf.openrocket.gui.components.UnitSelector;
import net.sf.openrocket.gui.dialogs.preset.ComponentPresetChooserDialog;
import net.sf.openrocket.l10n.Translator; import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.BodyTube; import net.sf.openrocket.rocketcomponent.BodyTube;
import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
import net.sf.openrocket.rocketcomponent.RocketComponent; import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application; import net.sf.openrocket.startup.Application;
import net.sf.openrocket.unit.UnitGroup; import net.sf.openrocket.unit.UnitGroup;
public class BodyTubeConfig extends RocketComponentConfig { public class BodyTubeConfig extends RocketComponentConfig {
private ComponentChangeListener listener;
private MotorConfig motorConfigPane = null; private MotorConfig motorConfigPane = null;
private DoubleModel maxLength; private DoubleModel maxLength;
private JComboBox presetComboBox; private JComboBox presetComboBox;
private static final Translator trans = Application.getTranslator(); private static final Translator trans = Application.getTranslator();
public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) { public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) {
super(d, c); super(d, c);
JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", "")); JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
//// Body tube template //// Body tube template
panel.add( new JLabel(trans.get("BodyTubecfg.lbl.Bodytubepreset")) ); // FIXME: Move to proper location
presetComboBox = new JComboBox(new BodyTubePresetModel(component)); panel.add(new JLabel());
panel.add(presetComboBox); presetComboBox = new JComboBox(new PresetModel(component));
{ presetComboBox.setEditable(false);
JButton opendialog = new JButton("o"); panel.add(presetComboBox, "wrap para");
opendialog.addActionListener(
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ComponentPresetChooserDialog dialog = new ComponentPresetChooserDialog(SwingUtilities.getWindowAncestor(BodyTubeConfig.this));
dialog.setVisible(true);
ComponentPreset preset = dialog.getSelectedComponentPreset();
}
});
panel.add( opendialog, "wrap" );
}
//// Body tube length //// Body tube length
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Bodytubelength"))); panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Bodytubelength")));
maxLength = new DoubleModel(2.0); maxLength = new DoubleModel(2.0);
DoubleModel length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0); DoubleModel length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
JSpinner spin = new JSpinner(length.getSpinnerModel()); JSpinner spin = new JSpinner(length.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(length), "growx"); panel.add(new UnitSelector(length), "growx");
panel.add(new BasicSlider(length.getSliderModel(0, 0.5, maxLength)), "w 100lp, wrap"); panel.add(new BasicSlider(length.getSliderModel(0, 0.5, maxLength)), "w 100lp, wrap");
//// Body tube diameter //// Body tube diameter
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Outerdiameter"))); panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Outerdiameter")));
DoubleModel od = new DoubleModel(component, "OuterRadius", 2, UnitGroup.UNITS_LENGTH, 0); DoubleModel od = new DoubleModel(component, "OuterRadius", 2, UnitGroup.UNITS_LENGTH, 0);
// Diameter = 2*Radius // Diameter = 2*Radius
spin = new JSpinner(od.getSpinnerModel()); spin = new JSpinner(od.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(od), "growx"); panel.add(new UnitSelector(od), "growx");
panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px"); panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
JCheckBox check = new JCheckBox(od.getAutomaticAction()); JCheckBox check = new JCheckBox(od.getAutomaticAction());
//// Automatic //// Automatic
check.setText(trans.get("BodyTubecfg.checkbox.Automatic")); check.setText(trans.get("BodyTubecfg.checkbox.Automatic"));
panel.add(check, "skip, span 2, wrap"); panel.add(check, "skip, span 2, wrap");
//// Inner diameter //// Inner diameter
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter"))); panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter")));
// Diameter = 2*Radius // Diameter = 2*Radius
DoubleModel m = new DoubleModel(component, "InnerRadius", 2, UnitGroup.UNITS_LENGTH, 0); DoubleModel m = new DoubleModel(component, "InnerRadius", 2, UnitGroup.UNITS_LENGTH, 0);
spin = new JSpinner(m.getSpinnerModel()); spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx"); panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap"); panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap");
//// Wall thickness //// Wall thickness
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Wallthickness"))); panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Wallthickness")));
m = new DoubleModel(component, "Thickness", UnitGroup.UNITS_LENGTH, 0); m = new DoubleModel(component, "Thickness", UnitGroup.UNITS_LENGTH, 0);
spin = new JSpinner(m.getSpinnerModel()); spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin)); spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx"); panel.add(spin, "growx");
panel.add(new UnitSelector(m), "growx"); panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 0px"); panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
//// Filled //// Filled
check = new JCheckBox(new BooleanModel(component, "Filled")); check = new JCheckBox(new BooleanModel(component, "Filled"));
check.setText(trans.get("BodyTubecfg.checkbox.Filled")); check.setText(trans.get("BodyTubecfg.checkbox.Filled"));
panel.add(check, "skip, span 2, wrap"); panel.add(check, "skip, span 2, wrap");
//// Material //// Material
panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK), panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK),
"cell 4 0, gapleft paragraph, aligny 0%, spany"); "cell 4 0, gapleft paragraph, aligny 0%, spany");
//// General and General properties //// General and General properties
tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel, tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel,
trans.get("BodyTubecfg.tab.Generalproperties"), 0); trans.get("BodyTubecfg.tab.Generalproperties"), 0);
@ -141,47 +123,17 @@ public class BodyTubeConfig extends RocketComponentConfig {
tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfigPane, tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfigPane,
trans.get("BodyTubecfg.tab.Motormountconf"), 1); trans.get("BodyTubecfg.tab.Motormountconf"), 1);
tabbedPane.setSelectedIndex(0); tabbedPane.setSelectedIndex(0);
// need to work in the max length for body tubes based on presets...
adjustPresetState();
listener = new ComponentChangeListener() {
@Override
public void componentChanged(ComponentChangeEvent e) {
adjustPresetState();
}
};
component.addChangeListener(listener);
} }
@Override @Override
public void updateFields() { public void updateFields() {
super.updateFields(); super.updateFields();
if (motorConfigPane != null) if (motorConfigPane != null)
motorConfigPane.updateFields(); motorConfigPane.updateFields();
} }
@Override
public void invalidateModels() {
super.invalidateModels();
component.removeChangeListener(listener);
}
private void adjustPresetState() {
BodyTube bt = (BodyTube) component;
if ( bt.getPresetComponent() != null ) {
ComponentPreset btPreset = bt.getPresetComponent();
maxLength.setValue( btPreset.get(ComponentPreset.LENGTH) );
} else {
// here we should be able to force the preset combo box to display empty.
// We set the selected index to -1 (undefined), then force a repaint.
presetComboBox.setSelectedIndex(-1);
presetComboBox.repaint();
maxLength.setValue(2.0);
}
}
} }

View File

@ -5,6 +5,7 @@ import java.util.Map;
import net.sf.openrocket.material.Material; import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish; import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
import net.sf.openrocket.util.BugException;
/** /**
@ -15,26 +16,29 @@ import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
* *
* @author Sampo Niskanen <sampo.niskanen@iki.fi> * @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/ */
public class ComponentPreset extends TypedPropertyMap { public class ComponentPreset {
private final Map<TypedKey<?>, Object> properties = new HashMap<TypedKey<?>, Object>();
// TODO - Implement clone. // TODO - Implement clone.
// Implement "freezing" so the object cannot be modified. // Implement "freezing" so the object cannot be modified.
public enum Type { public enum Type {
BodyTube, BODY_TUBE,
NoseCone NOSE_CONE
} }
public final static TypedKey<Double> LENGTH = new TypedKey<Double>("Length", Double.class); public final static TypedKey<Double> LENGTH = new TypedKey<Double>("Length", Double.class);
public final static TypedKey<Double> INNER_DIAMETER = new TypedKey<Double>("InnerDiameter", Double.class); public final static TypedKey<Double> INNER_DIAMETER = new TypedKey<Double>("InnerDiameter", Double.class);
public final static TypedKey<Double> OUTER_DIAMETER = new TypedKey<Double>("OuterDiameter", Double.class); public final static TypedKey<Double> OUTER_DIAMETER = new TypedKey<Double>("OuterDiameter", Double.class);
public final static TypedKey<Material> MATERIAL = new TypedKey<Material>("Material", Material.class); public final static TypedKey<Material> MATERIAL = new TypedKey<Material>("Material", Material.class);
public final static TypedKey<Finish> FINISH = new TypedKey<Finish>("Finish",Finish.class); public final static TypedKey<Finish> FINISH = new TypedKey<Finish>("Finish", Finish.class);
public final static TypedKey<Double> THICKNESS = new TypedKey<Double>("Thickness", Double.class); public final static TypedKey<Double> THICKNESS = new TypedKey<Double>("Thickness", Double.class);
public final static TypedKey<Boolean> FILLED = new TypedKey<Boolean>("Filled",Boolean.class); public final static TypedKey<Boolean> FILLED = new TypedKey<Boolean>("Filled", Boolean.class);
public final static TypedKey<Double> MASS = new TypedKey<Double>("Mass", Double.class); public final static TypedKey<Double> MASS = new TypedKey<Double>("Mass", Double.class);
public final static Map<String,TypedKey<?>> keyMap = new HashMap<String,TypedKey<?>>(); public final static Map<String, TypedKey<?>> keyMap = new HashMap<String, TypedKey<?>>();
static { static {
keyMap.put(LENGTH.getName(), LENGTH); keyMap.put(LENGTH.getName(), LENGTH);
keyMap.put(INNER_DIAMETER.getName(), INNER_DIAMETER); keyMap.put(INNER_DIAMETER.getName(), INNER_DIAMETER);
@ -50,42 +54,65 @@ public class ComponentPreset extends TypedPropertyMap {
private String partNo; private String partNo;
private String partDescription; private String partDescription;
private Type type; private Type type;
public ComponentPreset() {
}
public String getManufacturer() { public String getManufacturer() {
return manufacturer; return manufacturer;
} }
public void setManufacturer(String manufacturer) { public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer; this.manufacturer = manufacturer;
} }
public String getPartNo() { public String getPartNo() {
return partNo; return partNo;
} }
public void setPartNo(String partNo) { public void setPartNo(String partNo) {
this.partNo = partNo; this.partNo = partNo;
} }
public String getPartDescription() { public String getPartDescription() {
return partDescription; return partDescription;
} }
public void setPartDescription(String partDescription) { public void setPartDescription(String partDescription) {
this.partDescription = partDescription; this.partDescription = partDescription;
} }
public Type getType() { public Type getType() {
return type; return type;
} }
public void setType(Type type) { public void setType(Type type) {
this.type = type; this.type = type;
} }
public boolean has(Object key) {
return properties.containsKey(key);
}
@SuppressWarnings("unchecked")
public <T> T get(TypedKey<T> key) {
Object value = properties.get(key);
if (value == null) {
throw new BugException("Preset of type " + type + " did not contain key " + key + " mfg=" + manufacturer + " partNo=" + partNo);
}
return (T) value;
}
@SuppressWarnings("unchecked")
public <T> T put(TypedKey<T> key, T value) {
return (T) properties.put(key, value);
}
@Override
public String toString() {
return partNo;
}
} }

View File

@ -7,74 +7,64 @@ import java.util.Map.Entry;
import java.util.Set; import java.util.Set;
public class TypedPropertyMap { public class TypedPropertyMap {
private final Map<TypedKey<?>, Object> delegate; private final Map<TypedKey<?>, Object> delegate;
public TypedPropertyMap() { public TypedPropertyMap() {
delegate = new LinkedHashMap<TypedKey<?>,Object>(); delegate = new LinkedHashMap<TypedKey<?>, Object>();
} }
public int size() { public int size() {
return delegate.size(); return delegate.size();
} }
public boolean isEmpty() { public boolean isEmpty() {
return delegate.isEmpty(); return delegate.isEmpty();
} }
public boolean containsKey(Object key) { public boolean containsKey(Object key) {
return delegate.containsKey(key); return delegate.containsKey(key);
} }
public boolean containsValue(Object value) { public boolean containsValue(Object value) {
return delegate.containsValue(value); return delegate.containsValue(value);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T get(TypedKey<T> key) { public <T> T get(TypedKey<T> key) {
return (T) delegate.get(key); return (T) delegate.get(key);
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T put(TypedKey<T> key, T value) { public <T> T put(TypedKey<T> key, T value) {
return (T) delegate.put(key, value); return (T) delegate.put(key, value);
} }
public Object remove(Object key) { public Object remove(Object key) {
return delegate.remove(key); return delegate.remove(key);
} }
public void putAll(TypedPropertyMap other) { public void putAll(TypedPropertyMap other) {
if ( other == null ) { if (other == null) {
return; return;
} }
delegate.putAll(other.delegate); delegate.putAll(other.delegate);
} }
public void clear() { public void clear() {
delegate.clear(); delegate.clear();
} }
public Set<TypedKey<?>> keySet() { public Set<TypedKey<?>> keySet() {
return delegate.keySet(); return delegate.keySet();
} }
public Collection<Object> values() { public Collection<Object> values() {
return delegate.values(); return delegate.values();
} }
public Set<Entry<TypedKey<?>, Object>> entrySet() { public Set<Entry<TypedKey<?>, Object>> entrySet() {
return delegate.entrySet(); return delegate.entrySet();
} }
@Override
public boolean equals(Object o) {
return delegate.equals(o);
}
@Override
public int hashCode() {
return delegate.hashCode();
}
} }

View File

@ -52,7 +52,7 @@ public abstract class BodyComponent extends ExternalComponent {
@Override @Override
protected void loadFromPreset(ComponentPreset preset) { protected void loadFromPreset(ComponentPreset preset) {
if ( preset.containsKey(ComponentPreset.LENGTH) ) { if ( preset.has(ComponentPreset.LENGTH) ) {
this.setLength(preset.get(ComponentPreset.LENGTH)); this.setLength(preset.get(ComponentPreset.LENGTH));
} }

View File

@ -137,10 +137,10 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
@Override @Override
protected void loadFromPreset(ComponentPreset preset) { protected void loadFromPreset(ComponentPreset preset) {
this.autoRadius = false; this.autoRadius = false;
if ( preset.containsKey(ComponentPreset.OUTER_DIAMETER) ) { if ( preset.has(ComponentPreset.OUTER_DIAMETER) ) {
double outerDiameter = preset.get(ComponentPreset.OUTER_DIAMETER); double outerDiameter = preset.get(ComponentPreset.OUTER_DIAMETER);
this.outerRadius = outerDiameter/2.0; this.outerRadius = outerDiameter/2.0;
if ( preset.containsKey(ComponentPreset.INNER_DIAMETER) ) { if ( preset.has(ComponentPreset.INNER_DIAMETER) ) {
double innerDiameter = preset.get(ComponentPreset.INNER_DIAMETER); double innerDiameter = preset.get(ComponentPreset.INNER_DIAMETER);
this.thickness = (outerDiameter-innerDiameter) / 2.0; this.thickness = (outerDiameter-innerDiameter) / 2.0;
} }

View File

@ -134,7 +134,7 @@ public abstract class ExternalComponent extends RocketComponent {
// Surface finish is left unchanged // Surface finish is left unchanged
if ( preset.containsKey(ComponentPreset.MATERIAL ) ) { if ( preset.has(ComponentPreset.MATERIAL ) ) {
Material mat = preset.get(ComponentPreset.MATERIAL); Material mat = preset.get(ComponentPreset.MATERIAL);
if ( mat != null ) { if ( mat != null ) {
setMaterial(mat); setMaterial(mat);

View File

@ -148,10 +148,10 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
@Override @Override
protected void loadFromPreset(ComponentPreset preset) { protected void loadFromPreset(ComponentPreset preset) {
if ( preset.containsKey(ComponentPreset.THICKNESS) ) { if ( preset.has(ComponentPreset.THICKNESS) ) {
this.setThickness(preset.get(ComponentPreset.THICKNESS)); this.setThickness(preset.get(ComponentPreset.THICKNESS));
} }
if ( preset.containsKey(ComponentPreset.FILLED)) { if ( preset.has(ComponentPreset.FILLED)) {
this.setFilled(preset.get(ComponentPreset.FILLED)); this.setFilled(preset.get(ComponentPreset.FILLED));
} }