package net.sf.openrocket.database;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Collections;
import java.util.List;
-import java.util.Set;
-import net.sf.openrocket.file.preset.PresetCSVReader;
import net.sf.openrocket.preset.ComponentPreset;
-import net.sf.openrocket.preset.InvalidComponentPresetException;
-import net.sf.openrocket.preset.TypedPropertyMap;
-import net.sf.openrocket.startup.Application;
-import net.sf.openrocket.util.BugException;
-public class ComponentPresetDao {
+public interface ComponentPresetDao {
- // List of all ComponentPresets
- private final List<ComponentPreset> templates = new ArrayList<ComponentPreset>();
-
- // Package scope constructor to control creation pattern.
- public ComponentPresetDao() {}
-
- public void initialize() throws IOException {
-
- Set<String> favorites = Application.getPreferences().getComponentFavorites();
-
- InputStream is = ComponentPresetDao.class.getResourceAsStream("/datafiles/bodytubepresets.csv");
-
- PresetCSVReader parser = new PresetCSVReader(is);
- List<TypedPropertyMap> list = parser.parse();
- for( TypedPropertyMap o : list ) {
- try {
- ComponentPreset preset = ComponentPreset.create(o);
- if ( favorites.contains(preset.preferenceKey())) {
- preset.setFavorite(true);
- }
- this.insert(preset);
- } catch ( InvalidComponentPresetException ex ) {
- throw new BugException( ex );
- }
- }
-
-
- }
-
- public List<ComponentPreset> listAll() {
- return templates;
- }
-
- public void insert( ComponentPreset preset ) {
- templates.add(preset);
- }
-
- public List<ComponentPreset> listForType( ComponentPreset.Type type ) {
- if ( type == null ) {
- return Collections.<ComponentPreset>emptyList();
- }
-
- List<ComponentPreset> result = new ArrayList<ComponentPreset>(templates.size()/6);
-
- for( ComponentPreset preset : templates ) {
- if ( preset.get(ComponentPreset.TYPE).equals(type) ) {
- result.add(preset);
- }
- }
- return result;
+ public List<ComponentPreset> listAll();
+
+ public void insert( ComponentPreset preset );
- }
+ public List<ComponentPreset> listForType( ComponentPreset.Type type );
/**
* Return a list of component presets based on the type.
* @param favorite if true, only return the favorites. otherwise return all matching.
* @return
*/
- public List<ComponentPreset> listForType( ComponentPreset.Type type, boolean favorite ) {
-
- if ( !favorite ) {
- return listForType(type);
- }
-
- List<ComponentPreset> result = new ArrayList<ComponentPreset>(templates.size()/6);
-
- for( ComponentPreset preset : templates ) {
- if ( preset.isFavorite() && preset.get(ComponentPreset.TYPE).equals(type) ) {
- result.add(preset);
- }
- }
- return result;
-
-
- }
-
- public List<ComponentPreset> listForTypes( ComponentPreset.Type ... type ) {
-
- if( type == null || type.length == 0 ) {
- return Collections.<ComponentPreset>emptyList();
- }
-
- if (type.length == 1 ) {
- return listForType(type[0]);
- }
-
- List<ComponentPreset> result = new ArrayList<ComponentPreset>(templates.size()/6);
-
- for( ComponentPreset preset : templates ) {
- ComponentPreset.Type presetType = preset.get(ComponentPreset.TYPE);
- typeLoop: for( int i=0; i<type.length; i++ ) {
- if ( !presetType.equals(type) ) {
- result.add(preset);
- break typeLoop; // from inner loop.
- }
- }
+ public List<ComponentPreset> listForType( ComponentPreset.Type type, boolean favorite );
- }
- return result;
- }
+ public List<ComponentPreset> listForTypes( ComponentPreset.Type ... type );
- public void setFavorite( ComponentPreset preset, boolean favorite ) {
- preset.setFavorite(favorite);
- Application.getPreferences().setComponentFavorite( preset, favorite );
- }
+ public void setFavorite( ComponentPreset preset, boolean favorite );
}
\ No newline at end of file
--- /dev/null
+package net.sf.openrocket.database;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import net.sf.openrocket.file.Loader;
+import net.sf.openrocket.file.preset.PresetCSVReader;
+import net.sf.openrocket.preset.ComponentPreset;
+import net.sf.openrocket.preset.InvalidComponentPresetException;
+import net.sf.openrocket.preset.TypedPropertyMap;
+import net.sf.openrocket.startup.Application;
+import net.sf.openrocket.util.BugException;
+
+public class ComponentPresetDatabase extends Database<ComponentPreset> implements ComponentPresetDao {
+
+ private static class ComponentPresetLoader implements Loader<ComponentPreset> {
+
+ @Override
+ public Collection<ComponentPreset> load(InputStream stream,
+ String filename) throws IOException {
+ Set<String> favorites = Application.getPreferences().getComponentFavorites();
+
+ List<ComponentPreset> returnval = new ArrayList<ComponentPreset>();
+
+ InputStream is = ComponentPresetDao.class.getResourceAsStream("/datafiles/bodytubepresets.csv");
+
+ PresetCSVReader parser = new PresetCSVReader(is);
+ List<TypedPropertyMap> list = parser.parse();
+ for( TypedPropertyMap o : list ) {
+ try {
+ ComponentPreset preset = ComponentPreset.create(o);
+ if ( favorites.contains(preset.preferenceKey())) {
+ preset.setFavorite(true);
+ }
+ returnval.add(preset);
+ } catch ( InvalidComponentPresetException ex ) {
+ throw new BugException( ex );
+ }
+ }
+ return returnval;
+ }
+
+ }
+
+ public ComponentPresetDatabase() {
+ super(new ComponentPresetLoader());
+ }
+
+ @Override
+ public List<ComponentPreset> listAll() {
+ return list;
+ }
+
+ @Override
+ public void insert( ComponentPreset preset ) {
+ list.add(preset);
+ }
+
+ @Override
+ public List<ComponentPreset> listForType( ComponentPreset.Type type ) {
+ if ( type == null ) {
+ return Collections.<ComponentPreset>emptyList();
+ }
+
+ List<ComponentPreset> result = new ArrayList<ComponentPreset>(list.size()/6);
+
+ for( ComponentPreset preset : list ) {
+ if ( preset.get(ComponentPreset.TYPE).equals(type) ) {
+ result.add(preset);
+ }
+ }
+ return result;
+
+ }
+
+ /**
+ * Return a list of component presets based on the type.
+ * All components returned will be of Type type.
+ *
+ * @param type
+ * @param favorite if true, only return the favorites. otherwise return all matching.
+ * @return
+ */
+ @Override
+ public List<ComponentPreset> listForType( ComponentPreset.Type type, boolean favorite ) {
+
+ if ( !favorite ) {
+ return listForType(type);
+ }
+
+ List<ComponentPreset> result = new ArrayList<ComponentPreset>(list.size()/6);
+
+ for( ComponentPreset preset : list ) {
+ if ( preset.isFavorite() && preset.get(ComponentPreset.TYPE).equals(type) ) {
+ result.add(preset);
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public List<ComponentPreset> listForTypes( ComponentPreset.Type ... type ) {
+
+ if( type == null || type.length == 0 ) {
+ return Collections.<ComponentPreset>emptyList();
+ }
+
+ if (type.length == 1 ) {
+ return listForType(type[0]);
+ }
+
+ List<ComponentPreset> result = new ArrayList<ComponentPreset>(list.size()/6);
+
+ for( ComponentPreset preset : list ) {
+ ComponentPreset.Type presetType = preset.get(ComponentPreset.TYPE);
+ typeLoop: for( int i=0; i<type.length; i++ ) {
+ if ( !presetType.equals(type) ) {
+ result.add(preset);
+ break typeLoop; // from inner loop.
+ }
+ }
+
+ }
+ return result;
+ }
+
+ @Override
+ public void setFavorite( ComponentPreset preset, boolean favorite ) {
+ preset.setFavorite(favorite);
+ Application.getPreferences().setComponentFavorite( preset, favorite );
+ this.fireAddEvent(preset);
+ }
+
+}
package net.sf.openrocket.database;
import java.io.File;
+import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.jar.JarFile;
import net.sf.openrocket.file.Loader;
+import net.sf.openrocket.file.iterator.DirectoryIterator;
+import net.sf.openrocket.file.iterator.FileIterator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.startup.Application;
import net.sf.openrocket.util.JarUtil;
+import net.sf.openrocket.util.Pair;
public class Database<T extends Comparable<T>> extends AbstractSet<T> {
private static final LogHelper log = Application.getLogger();
- private final List<T> list = new ArrayList<T>();
+ protected final List<T> list = new ArrayList<T>();
private final ArrayList<DatabaseListener<T>> listeners =
new ArrayList<DatabaseListener<T>>();
private final Loader<T> loader;
//////// Directory loading
+ public void load( String dir, final String pattern ) throws IOException {
+
+ FileFilter filter = new FileFilter() {
+ @Override
+ public boolean accept(File pathname) {
+ return pathname.getName().matches(pattern);
+ }
+
+ };
+
+ FileIterator files = DirectoryIterator.findDirectory(dir, filter);
+ while( files != null && files.hasNext() ) {
+ Pair<String, InputStream> file = files.next();
+ try {
+ this.addAll(loader.load(file.getV(), file.getU()));
+ } catch (IOException e) {
+ log.warn("Error loading file " + file + ": " + e.getMessage(), e);
+ }
+ }
+ }
/**
* Load all files in a directory to the motor database. Only files with file
import javax.swing.AbstractListModel;
import javax.swing.ComboBoxModel;
+import net.sf.openrocket.database.Database;
+import net.sf.openrocket.database.DatabaseListener;
import net.sf.openrocket.l10n.Translator;
import net.sf.openrocket.logging.LogHelper;
import net.sf.openrocket.preset.ComponentPreset;
import net.sf.openrocket.rocketcomponent.RocketComponent;
import net.sf.openrocket.startup.Application;
-public class PresetModel extends AbstractListModel implements ComboBoxModel, ComponentChangeListener {
+public class PresetModel extends AbstractListModel implements ComboBoxModel, ComponentChangeListener, DatabaseListener<ComponentPreset> {
private static final LogHelper log = Application.getLogger();
private static final Translator trans = Application.getTranslator();
private final RocketComponent component;
private ComponentPreset previousPreset;
- private final List<ComponentPreset> presets;
+ private List<ComponentPreset> presets;
public PresetModel(RocketComponent component) {
presets = Application.getComponentPresetDao().listForType(component.getPresetType(), true);
}
}
- // FIXME: Make model invalidatable
-
+ @Override
+ public void elementAdded(ComponentPreset element, Database<ComponentPreset> source) {
+ presets = Application.getComponentPresetDao().listForType(component.getPresetType(), true);
+ this.fireContentsChanged(this, 0, getSize());
+ }
+
+ @Override
+ public void elementRemoved(ComponentPreset element, Database<ComponentPreset> source) {
+ presets = Application.getComponentPresetDao().listForType(component.getPresetType(), true);
+ this.fireContentsChanged(this, 0, getSize());
+ }
+
}
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
+import net.sf.openrocket.database.ComponentPresetDatabase;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.gui.SpinnerEditor;
import net.sf.openrocket.gui.adaptors.BooleanModel;
import net.sf.openrocket.unit.UnitGroup;
public class BodyTubeConfig extends RocketComponentConfig {
-
+
private MotorConfig motorConfigPane = null;
private DoubleModel maxLength;
private JComboBox presetComboBox;
+ private PresetModel presetModel;
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
// FIXME: Move to proper location
panel.add(new JLabel(trans.get("PresetModel.lbl.select")));
- presetComboBox = new JComboBox(new PresetModel(component));
+ presetModel = new PresetModel(component);
+ ((ComponentPresetDatabase)Application.getComponentPresetDao()).addDatabaseListener(presetModel);
+ presetComboBox = new JComboBox(presetModel);
presetComboBox.setEditable(false);
panel.add(presetComboBox, "wrap para");
//FIXME: temporarily put the select from table button in the config dialog.
panel.add( opendialog, "wrap" );
}
-
+
//// 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);
-
-
+
+
}
-
+
@Override
public void updateFields() {
super.updateFields();
if (motorConfigPane != null)
motorConfigPane.updateFields();
}
-
-
-
+
+ @Override
+ public void invalidateModels() {
+ super.invalidateModels();
+ ((ComponentPresetDatabase)Application.getComponentPresetDao()).removeChangeListener(presetModel);
+ }
+
+
}
double v = (Double) ComponentPresetChooserDialog.this.presets.get(row).get(key);
return new Value( v, key.getUnitGroup() );
} else {
- return ComponentPresetChooserDialog.this.presets.get(row);
+ return ComponentPresetChooserDialog.this.presets.get(row).get(key);
}
}
};
* @author Sampo Niskanen <sampo.niskanen@iki.fi>
*/
// FIXME - Implement clone.
-public class ComponentPreset {
+public class ComponentPreset implements Comparable<ComponentPreset> {
private final TypedPropertyMap properties = new TypedPropertyMap();
}
+ public Manufacturer getManufacturer() {
+ return properties.get(MANUFACTURER);
+ }
+
+ public String getPartNo() {
+ return properties.get(PARTNO);
+ }
+
public boolean has(Object key) {
return properties.containsKey(key);
}
this.favorite = favorite;
}
+ @Override
+ public int compareTo(ComponentPreset p2) {
+ int manuCompare = this.getManufacturer().getSimpleName().compareTo(p2.getManufacturer().getSimpleName());
+ if ( manuCompare != 0 )
+ return manuCompare;
+
+ int partNoCompare = this.getPartNo().compareTo(p2.getPartNo());
+ return partNoCompare;
+ }
+
@Override
public String toString() {
return get(MANUFACTURER).toString() + " " + get(PARTNO);
public String preferenceKey() {
return get(MANUFACTURER).toString() + "|" + get(PARTNO);
}
+
}
import java.util.Locale;
import java.util.prefs.Preferences;
-import net.sf.openrocket.database.ComponentPresetDao;
+import net.sf.openrocket.database.ComponentPresetDatabase;
import net.sf.openrocket.gui.util.SwingPreferences;
import net.sf.openrocket.l10n.DebugTranslator;
import net.sf.openrocket.l10n.L10N;
initializeL10n();
// Must be done after localization is initialized
- ComponentPresetDao componentPresetDao = new ComponentPresetDao();
- componentPresetDao.initialize();
+ ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase();
+ componentPresetDao.load("datafiles", ".*csv");
Application.setComponentPresetDao( componentPresetDao );
// Continue startup in Startup2 class (where Application is already set up)