1 package net.sf.openrocket.gui.adaptors;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
7 import javax.swing.AbstractListModel;
8 import javax.swing.ComboBoxModel;
9 import javax.swing.JButton;
10 import javax.swing.JDialog;
11 import javax.swing.JFrame;
12 import javax.swing.JLabel;
13 import javax.swing.JPanel;
14 import javax.swing.JSpinner;
15 import javax.swing.JTextField;
16 import javax.swing.SwingUtilities;
17 import javax.swing.event.ChangeEvent;
18 import javax.swing.event.ChangeListener;
20 import net.miginfocom.swing.MigLayout;
21 import net.sf.openrocket.database.Database;
22 import net.sf.openrocket.database.Databases;
23 import net.sf.openrocket.gui.components.UnitSelector;
24 import net.sf.openrocket.material.Material;
25 import net.sf.openrocket.rocketcomponent.ComponentChangeEvent;
26 import net.sf.openrocket.rocketcomponent.RocketComponent;
27 import net.sf.openrocket.unit.UnitGroup;
28 import net.sf.openrocket.util.Reflection;
30 public class MaterialModel extends AbstractListModel implements
31 ComboBoxModel, ChangeListener {
33 private static final String CUSTOM = "Custom";
36 private final RocketComponent component;
37 private final Material.Type type;
38 private final Database<Material> database;
40 private final Reflection.Method getMethod;
41 private final Reflection.Method setMethod;
44 public MaterialModel(RocketComponent component, Material.Type type) {
45 this(component, type, "Material");
48 public MaterialModel(RocketComponent component, Material.Type type, String name) {
49 this.component = component;
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.addChangeListener(this);
79 database.addChangeListener(this);
83 public Object getSelectedItem() {
84 return getMethod.invoke(component);
88 public void setSelectedItem(Object item) {
91 // Open custom material dialog in the future, after combo box has closed
92 SwingUtilities.invokeLater(new Runnable() {
95 AddMaterialDialog dialog = new AddMaterialDialog();
96 dialog.setVisible(true);
98 if (!dialog.okClicked)
101 Material material = Material.newMaterial(type,
102 dialog.nameField.getText().trim(),
103 dialog.density.getValue());
104 setMethod.invoke(component, material);
106 // TODO: HIGH: Allow saving added material to database
107 // if (dialog.addBox.isSelected()) {
108 // database.add(material);
113 } else if (item instanceof Material) {
115 setMethod.invoke(component, item);
118 assert(false): "Should not occur";
123 public Object getElementAt(int index) {
124 if (index == database.size()) {
126 } else if (index >= database.size()+1) {
129 return database.get(index);
133 public int getSize() {
134 return database.size() + 1;
139 public void stateChanged(ChangeEvent e) {
140 if (e instanceof ComponentChangeEvent) {
141 if (((ComponentChangeEvent)e).isMassChange()) {
142 this.fireContentsChanged(this, 0, 0);
145 this.fireContentsChanged(this, 0, database.size());
152 private class AddMaterialDialog extends JDialog {
154 private boolean okClicked = false;
155 private JTextField nameField;
156 private DoubleModel density;
157 // private JCheckBox addBox;
159 public AddMaterialDialog() {
160 super((JFrame)null, "Custom material", true);
162 Material material = (Material) getSelectedItem();
164 JPanel panel = new JPanel(new MigLayout("gap rel unrel","[][65lp::][30lp::]"));
166 panel.add(new JLabel("Material name:"));
167 nameField = new JTextField(15);
168 nameField.setText(material.getName());
169 panel.add(nameField,"span 2, growx, wrap");
171 panel.add(new JLabel("Material density:"));
172 density = new DoubleModel(material.getDensity(),UnitGroup.UNITS_DENSITY_BULK,0);
173 JSpinner spinner = new JSpinner(density.getSpinnerModel());
174 panel.add(spinner, "growx");
175 panel.add(new UnitSelector(density),"wrap");
177 // addBox = new JCheckBox("Add material to database");
178 // panel.add(addBox,"span, wrap");
180 JButton button = new JButton("OK");
181 button.addActionListener(new ActionListener() {
183 public void actionPerformed(ActionEvent e) {
185 AddMaterialDialog.this.setVisible(false);
188 panel.add(button,"span, split, tag ok");
190 button = new JButton("Cancel");
191 button.addActionListener(new ActionListener() {
193 public void actionPerformed(ActionEvent e) {
194 AddMaterialDialog.this.setVisible(false);
197 panel.add(button,"tag cancel");
199 this.setContentPane(panel);
201 this.setAlwaysOnTop(true);
202 this.setLocationRelativeTo(null);