1 package net.sf.openrocket.gui.dialogs;
3 import java.awt.Window;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.awt.event.MouseAdapter;
7 import java.awt.event.MouseEvent;
8 import java.awt.event.WindowAdapter;
9 import java.awt.event.WindowEvent;
10 import java.util.ArrayList;
11 import java.util.Iterator;
13 import javax.swing.JButton;
14 import javax.swing.JDialog;
15 import javax.swing.JLabel;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollPane;
18 import javax.swing.JTable;
19 import javax.swing.JTextField;
20 import javax.swing.ListSelectionModel;
21 import javax.swing.event.DocumentEvent;
22 import javax.swing.event.DocumentListener;
23 import javax.swing.table.AbstractTableModel;
24 import javax.swing.table.TableColumn;
25 import javax.swing.table.TableColumnModel;
27 import net.miginfocom.swing.MigLayout;
28 import net.sf.openrocket.document.OpenRocketDocument;
29 import net.sf.openrocket.gui.main.BasicFrame;
30 import net.sf.openrocket.motor.Motor;
31 import net.sf.openrocket.rocketcomponent.MotorMount;
32 import net.sf.openrocket.rocketcomponent.Rocket;
33 import net.sf.openrocket.rocketcomponent.RocketComponent;
34 import net.sf.openrocket.util.GUIUtil;
36 public class EditMotorConfigurationDialog extends JDialog {
38 private final Rocket rocket;
40 private final MotorMount[] mounts;
42 private final JTable configurationTable;
43 private final MotorConfigurationTableModel configurationTableModel;
46 private final JButton newConfButton, removeConfButton;
47 private final JButton selectMotorButton, removeMotorButton;
48 private final JTextField configurationNameField;
51 private String currentID = null;
52 private MotorMount currentMount = null;
54 // Positive when user is modifying configuration name
55 private int configurationNameModification = 0;
57 public EditMotorConfigurationDialog(final Rocket rocket, Window parent) {
58 super(parent, "Edit motor configurations");
61 this.setModalityType(ModalityType.DOCUMENT_MODAL);
63 this.setModalityType(ModalityType.APPLICATION_MODAL);
67 ArrayList<MotorMount> mountList = new ArrayList<MotorMount>();
68 Iterator<RocketComponent> iterator = rocket.deepIterator();
69 while (iterator.hasNext()) {
70 RocketComponent c = iterator.next();
71 if (c instanceof MotorMount) {
72 mountList.add((MotorMount)c);
75 mounts = mountList.toArray(new MotorMount[0]);
79 JPanel panel = new JPanel(new MigLayout("fill, flowy"));
82 //// Motor mount selection
84 JLabel label = new JLabel("<html><b>Motor mounts:</b>");
85 panel.add(label, "gapbottom para");
87 label = new JLabel("<html>Select which components function as motor mounts:");
88 panel.add(label,"ay 100%, w 1px, growx");
91 JTable table = new JTable(new MotorMountTableModel());
92 table.setTableHeader(null);
93 table.setShowVerticalLines(false);
94 table.setRowSelectionAllowed(false);
95 table.setColumnSelectionAllowed(false);
97 TableColumnModel columnModel = table.getColumnModel();
98 TableColumn col0 = columnModel.getColumn(0);
99 int w = table.getRowHeight() + 2;
101 col0.setPreferredWidth(w);
104 table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
106 JScrollPane scroll = new JScrollPane(table);
107 panel.add(scroll, "w 200lp, h 150lp, grow, wrap 20lp");
115 label = new JLabel("<html><b>Motor configurations:</b>");
116 panel.add(label, "spanx, gapbottom para");
119 label = new JLabel("Configuration name:");
120 String tip = "Leave name empty for default.";
121 label.setToolTipText(tip);
122 panel.add(label, "");
124 configurationNameField = new JTextField(10);
125 configurationNameField.setToolTipText(tip);
126 configurationNameField.getDocument().addDocumentListener(new DocumentListener() {
128 public void changedUpdate(DocumentEvent e) {
132 public void insertUpdate(DocumentEvent e) {
136 public void removeUpdate(DocumentEvent e) {
139 private void update() {
140 if (configurationNameModification != 0)
143 String text = configurationNameField.getText();
144 if (currentID != null) {
145 configurationNameModification++;
146 rocket.setMotorConfigurationName(currentID, text);
147 int row = configurationTable.getSelectedRow();
148 configurationTableModel.fireTableCellUpdated(row, 0);
150 configurationNameModification--;
154 panel.add(configurationNameField, "cell 2 1, gapright para");
156 newConfButton = new JButton("New configuration");
157 newConfButton.addActionListener(new ActionListener() {
159 public void actionPerformed(ActionEvent e) {
160 String id = rocket.newMotorConfigurationID();
161 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
162 configurationTableModel.fireTableDataChanged();
166 panel.add(newConfButton, "cell 3 1");
168 removeConfButton = new JButton("Remove configuration");
169 removeConfButton.addActionListener(new ActionListener() {
171 public void actionPerformed(ActionEvent e) {
172 if (currentID == null)
174 rocket.removeMotorConfigurationID(currentID);
175 rocket.getDefaultConfiguration().setMotorConfigurationID(null);
176 configurationTableModel.fireTableDataChanged();
180 panel.add(removeConfButton, "cell 4 1");
185 configurationTableModel = new MotorConfigurationTableModel();
186 configurationTable = new JTable(configurationTableModel);
187 configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
188 configurationTable.setCellSelectionEnabled(true);
190 configurationTable.addMouseListener(new MouseAdapter() {
192 public void mouseClicked(MouseEvent e) {
194 if (e.getClickCount() == 1) {
196 // Single click updates selection
199 } else if (e.getClickCount() == 2) {
201 // Double-click edits motor
210 scroll = new JScrollPane(configurationTable);
211 panel.add(scroll, "cell 1 2, spanx, w 500lp, h 150lp, grow");
214 selectMotorButton = new JButton("Select motor");
215 selectMotorButton.addActionListener(new ActionListener() {
217 public void actionPerformed(ActionEvent e) {
221 panel.add(selectMotorButton, "spanx, flowx, split 2, ax 50%");
224 removeMotorButton = new JButton("Remove motor");
225 removeMotorButton.addActionListener(new ActionListener() {
227 public void actionPerformed(ActionEvent e) {
231 panel.add(removeMotorButton, "ax 50%");
237 JButton close = new JButton("Close");
238 close.addActionListener(new ActionListener() {
240 public void actionPerformed(ActionEvent e) {
241 EditMotorConfigurationDialog.this.dispose();
244 panel.add(close, "spanx, right");
252 this.setLocationByPlatform(true);
253 GUIUtil.setDisposableDialogOptions(this, close);
256 final OpenRocketDocument document = BasicFrame.findDocument(rocket);
257 if (document != null) {
258 document.startUndo("Edit motor configurations");
259 this.addWindowListener(new WindowAdapter() {
261 public void windowClosed(WindowEvent e) {
271 private void updateEnabled() {
272 int column = configurationTable.getSelectedColumn();
273 int row = configurationTable.getSelectedRow();
275 if (column < 0 || row < 0) {
280 currentID = findID(row);
284 currentMount = findMount(column);
286 rocket.getDefaultConfiguration().setMotorConfigurationID(currentID);
290 if (configurationNameModification == 0) {
291 // Don't update name field when user is modifying it
292 configurationNameModification++;
294 configurationNameField.setEnabled(currentID != null);
295 if (currentID == null) {
296 configurationNameField.setText("");
298 configurationNameField.setText(rocket.getMotorConfigurationName(currentID));
301 configurationNameModification--;
303 removeConfButton.setEnabled(currentID != null);
304 selectMotorButton.setEnabled(currentMount != null && currentID != null);
305 removeMotorButton.setEnabled(currentMount != null && currentID != null);
311 private void selectMotor() {
312 if (currentID == null || currentMount == null)
315 MotorChooserDialog dialog = new MotorChooserDialog(currentMount.getMotor(currentID),
316 currentMount.getMotorDelay(currentID), currentMount.getMotorMountDiameter(),
318 dialog.setVisible(true);
319 Motor m = dialog.getSelectedMotor();
320 double d = dialog.getSelectedDelay();
323 currentMount.setMotor(currentID, m);
324 currentMount.setMotorDelay(currentID, d);
327 int row = configurationTable.getSelectedRow();
328 configurationTableModel.fireTableRowsUpdated(row, row);
333 private void removeMotor() {
334 if (currentID == null || currentMount == null)
337 currentMount.setMotor(currentID, null);
339 int row = configurationTable.getSelectedRow();
340 configurationTableModel.fireTableRowsUpdated(row, row);
345 private String findID(int row) {
346 return rocket.getMotorConfigurationIDs()[row+1];
350 private MotorMount findMount(int column) {
351 MotorMount mount = null;
354 for (MotorMount m: mounts) {
355 if (m.isMotorMount())
364 throw new IndexOutOfBoundsException("motor mount not found, column="+column);
371 * The table model for selecting whether components are motor mounts or not.
373 private class MotorMountTableModel extends AbstractTableModel {
376 public int getColumnCount() {
381 public int getRowCount() {
382 return mounts.length;
386 public Class<?> getColumnClass(int column) {
389 return Boolean.class;
395 throw new IndexOutOfBoundsException("column="+column);
400 public Object getValueAt(int row, int column) {
403 return new Boolean(mounts[row].isMotorMount());
406 return mounts[row].toString();
409 throw new IndexOutOfBoundsException("column="+column);
414 public boolean isCellEditable(int row, int column) {
419 public void setValueAt(Object value, int row, int column) {
420 if (column != 0 || !(value instanceof Boolean)) {
421 throw new IllegalArgumentException("column="+column+", value="+value);
424 mounts[row].setMotorMount((Boolean)value);
425 configurationTableModel.fireTableStructureChanged();
433 * The table model for selecting and editing the motor configurations.
435 private class MotorConfigurationTableModel extends AbstractTableModel {
438 public int getColumnCount() {
440 for (MotorMount m: mounts) {
441 if (m.isMotorMount())
448 public int getRowCount() {
449 return rocket.getMotorConfigurationIDs().length-1;
453 public Object getValueAt(int row, int column) {
455 String id = findID(row);
458 return rocket.getMotorConfigurationNameOrDescription(id);
461 MotorMount mount = findMount(column);
462 Motor motor = mount.getMotor(id);
466 String str = motor.getDesignation(mount.getMotorDelay(id));
467 int count = mount.getMotorCount();
469 str = "" + count + "\u00d7 " + str;
476 public String getColumnName(int column) {
478 return "Configuration name";
481 MotorMount mount = findMount(column);
482 String name = mount.toString();
483 int count = mount.getMotorCount();
485 name = name + " (\u00d7" + count + ")";