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.material.Material;
15 import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
16 import net.sf.openrocket.rocketcomponent.ComponentChangeListener;
17 import net.sf.openrocket.rocketcomponent.RocketComponent;
18 import net.sf.openrocket.util.Reflection;
20 public class MaterialModel extends AbstractListModel implements
21 ComboBoxModel, ComponentChangeListener, DatabaseListener<Material> {
23 private static final String CUSTOM = "Custom";
26 private final Component parentComponent;
28 private final RocketComponent component;
29 private final Material.Type type;
30 private final Database<Material> database;
32 private final Reflection.Method getMethod;
33 private final Reflection.Method setMethod;
36 public MaterialModel(Component parent, RocketComponent component, Material.Type type) {
37 this(parent, component, type, "Material");
40 public MaterialModel(Component parent, RocketComponent component, Material.Type type,
42 this.parentComponent = parent;
43 this.component = component;
48 this.database = Databases.LINE_MATERIAL;
52 this.database = Databases.BULK_MATERIAL;
56 this.database = Databases.SURFACE_MATERIAL;
60 throw new IllegalArgumentException("Unknown material type:"+type);
64 getMethod = new Reflection.Method(component.getClass().getMethod("get"+name));
65 setMethod = new Reflection.Method(component.getClass().getMethod("set"+name,
67 } catch (NoSuchMethodException e) {
68 throw new IllegalArgumentException("get/is methods for material " +
69 "not present in class "+component.getClass().getCanonicalName());
72 component.addComponentChangeListener(this);
73 database.addDatabaseListener(this);
77 public Object getSelectedItem() {
78 return getMethod.invoke(component);
82 public void setSelectedItem(Object item) {
84 // Clear selection - huh?
90 // Open custom material dialog in the future, after combo box has closed
91 SwingUtilities.invokeLater(new Runnable() {
94 CustomMaterialDialog dialog = new CustomMaterialDialog(
95 SwingUtilities.getWindowAncestor(parentComponent),
96 (Material) getSelectedItem(), true,
97 "Define custom material");
99 dialog.setVisible(true);
101 if (!dialog.getOkClicked())
104 Material material = dialog.getMaterial();
105 setMethod.invoke(component, material);
107 if (dialog.isAddSelected()) {
108 database.add(material);
113 } else if (item instanceof Material) {
115 setMethod.invoke(component, item);
118 throw new IllegalArgumentException("Illegal item class " + item.getClass() +
124 public Object getElementAt(int index) {
125 if (index == database.size()) {
127 } else if (index >= database.size()+1) {
130 return database.get(index);
134 public int getSize() {
135 return database.size() + 1;
140 //////// Change listeners
143 public void componentChanged(ComponentChangeEvent e) {
144 if (((ComponentChangeEvent)e).isMassChange()) {
145 this.fireContentsChanged(this, 0, 0);
150 public void elementAdded(Material element, Database<Material> source) {
151 this.fireContentsChanged(this, 0, database.size());
155 public void elementRemoved(Material element, Database<Material> source) {
156 this.fireContentsChanged(this, 0, database.size());