1 package net.sf.openrocket.gui.adaptors;
4 import java.awt.Component;
6 import javax.swing.AbstractListModel;
7 import javax.swing.ComboBoxModel;
8 import javax.swing.SwingUtilities;
10 import net.sf.openrocket.database.Database;
11 import net.sf.openrocket.database.DatabaseListener;
12 import net.sf.openrocket.database.Databases;
13 import net.sf.openrocket.gui.dialogs.CustomMaterialDialog;
14 import net.sf.openrocket.l10n.Translator;
15 import net.sf.openrocket.material.Material;
16 import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
17 import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
18 import net.sf.openrocket.rocketcomponent.RocketComponent;
19 import net.sf.openrocket.startup.Application;
20 import net.sf.openrocket.util.Reflection;
22 public class MaterialModel extends AbstractListModel implements
23 ComboBoxModel, ComponentChangeListener, DatabaseListener<Material> {
25 private final String custom;
28 private final Component parentComponent;
30 private final RocketComponent component;
31 private final Material.Type type;
32 private final Database<Material> database;
34 private final Reflection.Method getMethod;
35 private final Reflection.Method setMethod;
36 private static final Translator trans = Application.getTranslator();
39 public MaterialModel(Component parent, RocketComponent component, Material.Type type) {
41 //this(parent, component, type, trans.get("MaterialModel.title.Material"));
42 this(parent, component, type, "Material");
45 public MaterialModel(Component parent, RocketComponent component, Material.Type type,
47 this.parentComponent = parent;
48 this.component = component;
50 this.custom = trans.get ("Material.CUSTOM");
54 this.database = Databases.LINE_MATERIAL;
58 this.database = Databases.BULK_MATERIAL;
62 this.database = Databases.SURFACE_MATERIAL;
66 throw new IllegalArgumentException("Unknown material type:"+type);
70 getMethod = new Reflection.Method(component.getClass().getMethod("get"+name));
71 setMethod = new Reflection.Method(component.getClass().getMethod("set"+name,
73 } catch (NoSuchMethodException e) {
74 throw new IllegalArgumentException("get/is methods for material " +
75 "not present in class "+component.getClass().getCanonicalName());
78 component.addComponentChangeListener(this);
79 database.addDatabaseListener(this);
83 public Object getSelectedItem() {
84 return getMethod.invoke(component);
88 public void setSelectedItem(Object item) {
90 // Clear selection - huh?
96 // Open custom material dialog in the future, after combo box has closed
97 SwingUtilities.invokeLater(new Runnable() {
100 CustomMaterialDialog dialog = new CustomMaterialDialog(
101 SwingUtilities.getWindowAncestor(parentComponent),
102 (Material) getSelectedItem(), true,
103 //// Define custom material
104 trans.get("MaterialModel.title.Defcustmat"));
106 dialog.setVisible(true);
108 if (!dialog.getOkClicked())
111 Material material = dialog.getMaterial();
112 setMethod.invoke(component, material);
114 if (dialog.isAddSelected()) {
115 database.add(material);
120 } else if (item instanceof Material) {
122 setMethod.invoke(component, item);
125 throw new IllegalArgumentException("Illegal item class " + item.getClass() +
131 public Object getElementAt(int index) {
132 if (index == database.size()) {
134 } else if (index >= database.size()+1) {
137 return database.get(index);
141 public int getSize() {
142 return database.size() + 1;
147 //////// Change listeners
150 public void componentChanged(ComponentChangeEvent e) {
151 if (((ComponentChangeEvent)e).isMassChange()) {
152 this.fireContentsChanged(this, 0, 0);
157 public void elementAdded(Material element, Database<Material> source) {
158 this.fireContentsChanged(this, 0, database.size());
162 public void elementRemoved(Material element, Database<Material> source) {
163 this.fireContentsChanged(this, 0, database.size());