1 package net.sf.openrocket.gui.configdialog;
4 import java.awt.Component;
5 import java.awt.Container;
7 import java.awt.event.ActionEvent;
8 import java.awt.event.ActionListener;
10 import javax.swing.JButton;
11 import javax.swing.JCheckBox;
12 import javax.swing.JComboBox;
13 import javax.swing.JLabel;
14 import javax.swing.JPanel;
15 import javax.swing.JSpinner;
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.gui.SpinnerEditor;
22 import net.sf.openrocket.gui.adaptors.BooleanModel;
23 import net.sf.openrocket.gui.adaptors.DoubleModel;
24 import net.sf.openrocket.gui.adaptors.EnumModel;
25 import net.sf.openrocket.gui.adaptors.MotorConfigurationModel;
26 import net.sf.openrocket.gui.components.BasicSlider;
27 import net.sf.openrocket.gui.components.StyledLabel;
28 import net.sf.openrocket.gui.components.UnitSelector;
29 import net.sf.openrocket.gui.dialogs.motor.MotorChooserDialog;
30 import net.sf.openrocket.motor.Motor;
31 import net.sf.openrocket.motor.ThrustCurveMotor;
32 import net.sf.openrocket.rocketcomponent.Configuration;
33 import net.sf.openrocket.rocketcomponent.MotorMount;
34 import net.sf.openrocket.rocketcomponent.Rocket;
35 import net.sf.openrocket.rocketcomponent.RocketComponent;
36 import net.sf.openrocket.rocketcomponent.MotorMount.IgnitionEvent;
37 import net.sf.openrocket.unit.UnitGroup;
39 public class MotorConfig extends JPanel {
41 private final Rocket rocket;
42 private final MotorMount mount;
43 private final Configuration configuration;
45 private JLabel motorLabel;
47 public MotorConfig(MotorMount motorMount) {
48 super(new MigLayout("fill"));
50 this.rocket = ((RocketComponent) motorMount).getRocket();
51 this.mount = motorMount;
52 this.configuration = ((RocketComponent) motorMount).getRocket().getDefaultConfiguration();
56 model = new BooleanModel(motorMount, "MotorMount");
57 JCheckBox check = new JCheckBox(model);
58 check.setText("This component is a motor mount");
59 this.add(check, "wrap");
62 panel = new JPanel(new MigLayout("fill"));
63 this.add(panel, "grow, wrap");
66 // Motor configuration selector
67 panel.add(new JLabel("Motor configuration:"), "shrink");
69 JComboBox combo = new JComboBox(new MotorConfigurationModel(configuration));
70 panel.add(combo, "growx");
72 configuration.addChangeListener(new ChangeListener() {
74 public void stateChanged(ChangeEvent e) {
79 JButton button = new JButton("New");
80 button.addActionListener(new ActionListener() {
82 public void actionPerformed(ActionEvent e) {
83 String id = rocket.newMotorConfigurationID();
84 configuration.setMotorConfigurationID(id);
87 panel.add(button, "wrap unrel");
91 panel.add(new JLabel("Current motor:"), "shrink");
93 motorLabel = new JLabel();
94 motorLabel.setFont(motorLabel.getFont().deriveFont(Font.BOLD));
96 panel.add(motorLabel, "wrap unrel");
101 panel.add(new JLabel("Motor overhang:"));
103 DoubleModel dm = new DoubleModel(motorMount, "MotorOverhang", UnitGroup.UNITS_LENGTH);
105 JSpinner spin = new JSpinner(dm.getSpinnerModel());
106 spin.setEditor(new SpinnerEditor(spin));
107 panel.add(spin, "span, split, width :65lp:");
109 panel.add(new UnitSelector(dm), "width :30lp:");
110 panel.add(new BasicSlider(dm.getSliderModel(-0.02, 0.06)), "w 100lp, wrap unrel");
114 // Select ignition event
115 panel.add(new JLabel("Ignition at:"), "");
117 combo = new JComboBox(new EnumModel<IgnitionEvent>(mount, "IgnitionEvent"));
118 panel.add(combo, "growx, wrap");
121 panel.add(new JLabel("plus"), "gap indent, skip 1, span, split");
123 dm = new DoubleModel(mount, "IgnitionDelay", 0);
124 spin = new JSpinner(dm.getSpinnerModel());
125 spin.setEditor(new SpinnerEditor(spin));
126 panel.add(spin, "gap rel rel");
128 panel.add(new JLabel("seconds"), "wrap unrel");
133 RocketComponent c = (RocketComponent) mount;
135 int stages = c.getChildCount();
138 panel.add(new StyledLabel("The current design has only one stage. " +
139 "Stages can be added by clicking \"New stage\".", -1),
140 "spanx, right, wrap para");
142 panel.add(new StyledLabel("The current design has " + stages + " stages.", -1),
143 "skip 1, spanx, wrap para");
147 // Select etc. buttons
148 button = new JButton("Select motor");
149 button.addActionListener(new ActionListener() {
151 public void actionPerformed(ActionEvent e) {
152 String id = configuration.getMotorConfigurationID();
154 MotorChooserDialog dialog = new MotorChooserDialog(mount.getMotor(id),
155 mount.getMotorDelay(id), mount.getMotorMountDiameter(),
156 SwingUtilities.getWindowAncestor(MotorConfig.this));
157 dialog.setVisible(true);
158 Motor m = dialog.getSelectedMotor();
159 double d = dialog.getSelectedDelay();
163 id = rocket.newMotorConfigurationID();
164 configuration.setMotorConfigurationID(id);
166 mount.setMotor(id, m);
167 mount.setMotorDelay(id, d);
172 panel.add(button, "span, split, growx");
174 button = new JButton("Remove motor");
175 button.addActionListener(new ActionListener() {
177 public void actionPerformed(ActionEvent e) {
178 mount.setMotor(configuration.getMotorConfigurationID(), null);
182 panel.add(button, "growx, wrap");
188 // Set enabled status
190 setDeepEnabled(panel, motorMount.isMotorMount());
191 check.addChangeListener(new ChangeListener() {
193 public void stateChanged(ChangeEvent e) {
194 setDeepEnabled(panel, mount.isMotorMount());
200 public void updateFields() {
201 String id = configuration.getMotorConfigurationID();
202 Motor m = mount.getMotor(id);
204 motorLabel.setText("None");
207 if (m instanceof ThrustCurveMotor)
208 str = ((ThrustCurveMotor) m).getManufacturer() + " ";
209 str += m.getDesignation(mount.getMotorDelay(id));
210 motorLabel.setText(str);
215 private static void setDeepEnabled(Component component, boolean enabled) {
216 component.setEnabled(enabled);
217 if (component instanceof Container) {
218 for (Component c : ((Container) component).getComponents()) {
219 setDeepEnabled(c, enabled);