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) {
85 // Open custom material dialog in the future, after combo box has closed
86 SwingUtilities.invokeLater(new Runnable() {
89 CustomMaterialDialog dialog = new CustomMaterialDialog(
90 SwingUtilities.getWindowAncestor(parentComponent),
91 (Material) getSelectedItem(), true,
92 "Define custom material");
94 dialog.setVisible(true);
96 if (!dialog.getOkClicked())
99 Material material = dialog.getMaterial();
100 setMethod.invoke(component, material);
102 if (dialog.isAddSelected()) {
103 database.add(material);
108 } else if (item instanceof Material) {
110 setMethod.invoke(component, item);
113 throw new IllegalArgumentException("Illegal item class " + item.getClass() +
119 public Object getElementAt(int index) {
120 if (index == database.size()) {
122 } else if (index >= database.size()+1) {
125 return database.get(index);
129 public int getSize() {
130 return database.size() + 1;
135 //////// Change listeners
138 public void componentChanged(ComponentChangeEvent e) {
139 if (((ComponentChangeEvent)e).isMassChange()) {
140 this.fireContentsChanged(this, 0, 0);
145 public void elementAdded(Material element, Database<Material> source) {
146 this.fireContentsChanged(this, 0, database.size());
150 public void elementRemoved(Material element, Database<Material> source) {
151 this.fireContentsChanged(this, 0, database.size());