-Manufacturer,PartNo,id(cm),od(cm),maxlength(cm)\r
+Manufacturer,PartNo,InnerDiameter,OuterDiameter,Length\r
Semroc,BT-3,0.8865,0.9525,45.72\r
Semroc,BT-3H,0.8865,0.9525,7.62\r
Semroc,BT-3XW,0.8865,0.9525,3.81\r
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.
+
+PresetModel.lbl.select = Select preset:
+PresetModel.lbl.database = From database...
+
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.preset.TypedKey;
-import net.sf.openrocket.rocketcomponent.BodyTube;
import au.com.bytecode.opencsv.CSVReader;
public class PresetCSVReader {
-
+
private InputStream is;
private ColumnDefinition[] columns;
- public PresetCSVReader( InputStream is ) {
+ public PresetCSVReader(InputStream is) {
this.is = is;
}
public List<ComponentPreset> parse() throws IOException {
-
+
List<ComponentPreset> templates = new ArrayList<ComponentPreset>();
-
+
InputStreamReader r = new InputStreamReader(is);
-
+
// 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();
if (headers == null || headers.length == 0) {
}
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];
- if( "Manufacturer".equals(h) ) {
+ if ("Manufacturer".equals(h)) {
columns[i] = new ColumnDefinition.Manufactuer();
- } else if ( "PartNumber".equals(h) ) {
+ } else if ("PartNo".equals(h)) {
columns[i] = new ColumnDefinition.PartNumber();
- } else if ( "Type".equals(h) ) {
+ } else if ("Type".equals(h)) {
columns[i] = new ColumnDefinition.Type();
} else {
TypedKey key = ComponentPreset.keyMap.get(h);
- if ( key == null ) {
+ if (key == null) {
throw new RuntimeException("Invalid parameter key " + h + " in file");
}
- columns[i] = new ColumnDefinition.Parameter( key );
+ columns[i] = new ColumnDefinition.Parameter(key);
}
}
String[] line;
- while( (line = reader.readNext()) != null ) {
+ while ((line = reader.readNext()) != null) {
ComponentPreset preset = new ComponentPreset();
- for( int i = 0; i< headers.length; i++ ) {
- if ( i > line.length ) {
+ for (int i = 0; i < headers.length; i++) {
+ if (i > line.length) {
break;
}
String value = line[i];
}
templates.add(preset);
}
-
+
return templates;
}
+++ /dev/null
-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);
- }
- }
-
-}
--- /dev/null
+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
+
+}
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.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
-import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
import net.sf.openrocket.document.OpenRocketDocument;
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.DoubleModel;
+import net.sf.openrocket.gui.adaptors.PresetModel;
import net.sf.openrocket.gui.components.BasicSlider;
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.material.Material;
-import net.sf.openrocket.preset.ComponentPreset;
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.startup.Application;
import net.sf.openrocket.unit.UnitGroup;
public class BodyTubeConfig extends RocketComponentConfig {
-
- private ComponentChangeListener listener;
+
private MotorConfig motorConfigPane = null;
private DoubleModel maxLength;
private JComboBox presetComboBox;
private static final Translator trans = Application.getTranslator();
-
+
public BodyTubeConfig(OpenRocketDocument d, RocketComponent c) {
super(d, c);
-
+
JPanel panel = new JPanel(new MigLayout("gap rel unrel", "[][65lp::][30lp::][]", ""));
-
+
+
+
//// Body tube template
- panel.add( new JLabel(trans.get("BodyTubecfg.lbl.Bodytubepreset")) );
- presetComboBox = new JComboBox(new BodyTubePresetModel(component));
- panel.add(presetComboBox);
- {
- JButton opendialog = new JButton("o");
- 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" );
- }
-
+ // FIXME: Move to proper location
+ panel.add(new JLabel());
+ presetComboBox = new JComboBox(new PresetModel(component));
+ presetComboBox.setEditable(false);
+ panel.add(presetComboBox, "wrap para");
+
+
+
//// Body tube length
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Bodytubelength")));
-
+
maxLength = new DoubleModel(2.0);
DoubleModel length = new DoubleModel(component, "Length", UnitGroup.UNITS_LENGTH, 0);
-
+
JSpinner spin = new JSpinner(length.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx");
-
+
panel.add(new UnitSelector(length), "growx");
panel.add(new BasicSlider(length.getSliderModel(0, 0.5, maxLength)), "w 100lp, wrap");
-
-
+
+
//// Body tube diameter
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Outerdiameter")));
-
+
DoubleModel od = new DoubleModel(component, "OuterRadius", 2, UnitGroup.UNITS_LENGTH, 0);
// Diameter = 2*Radius
-
+
spin = new JSpinner(od.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx");
-
+
panel.add(new UnitSelector(od), "growx");
panel.add(new BasicSlider(od.getSliderModel(0, 0.04, 0.2)), "w 100lp, wrap 0px");
-
+
JCheckBox check = new JCheckBox(od.getAutomaticAction());
//// Automatic
check.setText(trans.get("BodyTubecfg.checkbox.Automatic"));
panel.add(check, "skip, span 2, wrap");
-
-
+
+
//// Inner diameter
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Innerdiameter")));
-
+
// Diameter = 2*Radius
DoubleModel m = new DoubleModel(component, "InnerRadius", 2, UnitGroup.UNITS_LENGTH, 0);
-
-
+
+
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx");
-
+
panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(new DoubleModel(0), od)), "w 100lp, wrap");
-
-
+
+
//// Wall thickness
panel.add(new JLabel(trans.get("BodyTubecfg.lbl.Wallthickness")));
-
+
m = new DoubleModel(component, "Thickness", UnitGroup.UNITS_LENGTH, 0);
-
+
spin = new JSpinner(m.getSpinnerModel());
spin.setEditor(new SpinnerEditor(spin));
panel.add(spin, "growx");
-
+
panel.add(new UnitSelector(m), "growx");
panel.add(new BasicSlider(m.getSliderModel(0, 0.01)), "w 100lp, wrap 0px");
-
+
//// Filled
check = new JCheckBox(new BooleanModel(component, "Filled"));
check.setText(trans.get("BodyTubecfg.checkbox.Filled"));
panel.add(check, "skip, span 2, wrap");
-
-
+
+
//// Material
panel.add(materialPanel(new JPanel(new MigLayout()), Material.Type.BULK),
"cell 4 0, gapleft paragraph, aligny 0%, spany");
-
+
//// General and General properties
tabbedPane.insertTab(trans.get("BodyTubecfg.tab.General"), null, panel,
trans.get("BodyTubecfg.tab.Generalproperties"), 0);
tabbedPane.insertTab(trans.get("BodyTubecfg.tab.Motor"), null, motorConfigPane,
trans.get("BodyTubecfg.tab.Motormountconf"), 1);
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
public void updateFields() {
super.updateFields();
if (motorConfigPane != null)
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);
- }
- }
-
+
+
+
}
import net.sf.openrocket.material.Material;
import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
+import net.sf.openrocket.util.BugException;
/**
*
* @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.
// Implement "freezing" so the object cannot be modified.
public enum Type {
- BodyTube,
- NoseCone
+ BODY_TUBE,
+ NOSE_CONE
}
-
+
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> OUTER_DIAMETER = new TypedKey<Double>("OuterDiameter", Double.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<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 Map<String,TypedKey<?>> keyMap = new HashMap<String,TypedKey<?>>();
+ public final static Map<String, TypedKey<?>> keyMap = new HashMap<String, TypedKey<?>>();
static {
keyMap.put(LENGTH.getName(), LENGTH);
keyMap.put(INNER_DIAMETER.getName(), INNER_DIAMETER);
private String partNo;
private String partDescription;
private Type type;
-
- public ComponentPreset() {
-
- }
-
+
+
public String getManufacturer() {
return manufacturer;
}
-
+
public void setManufacturer(String manufacturer) {
this.manufacturer = manufacturer;
}
-
+
public String getPartNo() {
return partNo;
}
-
+
public void setPartNo(String partNo) {
this.partNo = partNo;
}
-
+
public String getPartDescription() {
return partDescription;
}
-
+
public void setPartDescription(String partDescription) {
this.partDescription = partDescription;
}
-
+
public Type getType() {
return type;
}
-
+
public void setType(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;
+ }
+
}
import java.util.Set;
public class TypedPropertyMap {
-
+
private final Map<TypedKey<?>, Object> delegate;
public TypedPropertyMap() {
- delegate = new LinkedHashMap<TypedKey<?>,Object>();
+ delegate = new LinkedHashMap<TypedKey<?>, Object>();
}
-
+
public int size() {
return delegate.size();
}
-
+
public boolean isEmpty() {
return delegate.isEmpty();
}
-
+
public boolean containsKey(Object key) {
return delegate.containsKey(key);
}
-
+
public boolean containsValue(Object value) {
return delegate.containsValue(value);
}
-
+
@SuppressWarnings("unchecked")
public <T> T get(TypedKey<T> key) {
return (T) delegate.get(key);
}
-
+
@SuppressWarnings("unchecked")
public <T> T put(TypedKey<T> key, T value) {
return (T) delegate.put(key, value);
}
-
+
public Object remove(Object key) {
return delegate.remove(key);
}
-
+
public void putAll(TypedPropertyMap other) {
- if ( other == null ) {
+ if (other == null) {
return;
}
delegate.putAll(other.delegate);
}
-
+
public void clear() {
delegate.clear();
}
-
+
public Set<TypedKey<?>> keySet() {
return delegate.keySet();
}
-
+
public Collection<Object> values() {
return delegate.values();
}
-
+
public Set<Entry<TypedKey<?>, Object>> entrySet() {
return delegate.entrySet();
}
-
- @Override
- public boolean equals(Object o) {
- return delegate.equals(o);
- }
-
- @Override
- public int hashCode() {
- return delegate.hashCode();
- }
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
- if ( preset.containsKey(ComponentPreset.LENGTH) ) {
+ if ( preset.has(ComponentPreset.LENGTH) ) {
this.setLength(preset.get(ComponentPreset.LENGTH));
}
@Override
protected void loadFromPreset(ComponentPreset preset) {
this.autoRadius = false;
- if ( preset.containsKey(ComponentPreset.OUTER_DIAMETER) ) {
+ if ( preset.has(ComponentPreset.OUTER_DIAMETER) ) {
double outerDiameter = preset.get(ComponentPreset.OUTER_DIAMETER);
this.outerRadius = outerDiameter/2.0;
- if ( preset.containsKey(ComponentPreset.INNER_DIAMETER) ) {
+ if ( preset.has(ComponentPreset.INNER_DIAMETER) ) {
double innerDiameter = preset.get(ComponentPreset.INNER_DIAMETER);
this.thickness = (outerDiameter-innerDiameter) / 2.0;
}
// Surface finish is left unchanged
- if ( preset.containsKey(ComponentPreset.MATERIAL ) ) {
+ if ( preset.has(ComponentPreset.MATERIAL ) ) {
Material mat = preset.get(ComponentPreset.MATERIAL);
if ( mat != null ) {
setMaterial(mat);
@Override
protected void loadFromPreset(ComponentPreset preset) {
- if ( preset.containsKey(ComponentPreset.THICKNESS) ) {
+ if ( preset.has(ComponentPreset.THICKNESS) ) {
this.setThickness(preset.get(ComponentPreset.THICKNESS));
}
- if ( preset.containsKey(ComponentPreset.FILLED)) {
+ if ( preset.has(ComponentPreset.FILLED)) {
this.setFilled(preset.get(ComponentPreset.FILLED));
}