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-3H,0.8865,0.9525,7.62
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.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,7 +8,6 @@ import java.util.List;
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 {
@ -39,7 +38,7 @@ public class PresetCSVReader {
String h = headers[i];
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)) {
columns[i] = new ColumnDefinition.Type();

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,39 +1,29 @@
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;
@ -44,24 +34,16 @@ public class BodyTubeConfig extends RocketComponentConfig {
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" );
}
//// Body tube template
// 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")));
@ -142,18 +124,6 @@ public class BodyTubeConfig extends RocketComponentConfig {
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);
}
@ -164,24 +134,6 @@ public class BodyTubeConfig extends RocketComponentConfig {
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.rocketcomponent.ExternalComponent.Finish;
import net.sf.openrocket.util.BugException;
/**
@ -15,14 +16,17 @@ import net.sf.openrocket.rocketcomponent.ExternalComponent.Finish;
*
* @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);
@ -51,9 +55,6 @@ public class ComponentPreset extends TypedPropertyMap {
private String partDescription;
private Type type;
public ComponentPreset() {
}
public String getManufacturer() {
return manufacturer;
@ -88,4 +89,30 @@ public class ComponentPreset extends TypedPropertyMap {
}
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

@ -67,14 +67,4 @@ public class TypedPropertyMap {
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
protected void loadFromPreset(ComponentPreset preset) {
if ( preset.containsKey(ComponentPreset.LENGTH) ) {
if ( preset.has(ComponentPreset.LENGTH) ) {
this.setLength(preset.get(ComponentPreset.LENGTH));
}

View File

@ -137,10 +137,10 @@ public class BodyTube extends SymmetricComponent implements MotorMount, Coaxial
@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;
}

View File

@ -134,7 +134,7 @@ public abstract class ExternalComponent extends RocketComponent {
// 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);

View File

@ -148,10 +148,10 @@ public abstract class SymmetricComponent extends BodyComponent implements Radial
@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));
}