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.gui.main.MotorChooserDialog;
31 import net.sf.openrocket.rocketcomponent.Motor;
32 import net.sf.openrocket.rocketcomponent.MotorMount;
33 import net.sf.openrocket.rocketcomponent.Rocket;
34 import net.sf.openrocket.rocketcomponent.RocketComponent;
35 import net.sf.openrocket.util.GUIUtil;
37 public class EditMotorConfigurationDialog extends JDialog {
39 private final Rocket rocket;
41 private final MotorMount[] mounts;
43 private final JTable configurationTable;
44 private final MotorConfigurationTableModel configurationTableModel;
47 private final JButton newConfButton, removeConfButton;
48 private final JButton selectMotorButton, removeMotorButton;
49 private final JTextField configurationNameField;
52 private String currentID = null;
53 private MotorMount currentMount = null;
55 public EditMotorConfigurationDialog(final Rocket rocket, Window parent) {
56 super(parent, "Edit motor configurations");
59 this.setModalityType(ModalityType.DOCUMENT_MODAL);
61 this.setModalityType(ModalityType.APPLICATION_MODAL);
65 ArrayList<MotorMount> mountList = new ArrayList<MotorMount>();
66 Iterator<RocketComponent> iterator = rocket.deepIterator();
67 while (iterator.hasNext()) {
68 RocketComponent c = iterator.next();
69 if (c instanceof MotorMount) {
70 mountList.add((MotorMount)c);
73 mounts = mountList.toArray(new MotorMount[0]);
77 JPanel panel = new JPanel(new MigLayout("fill, flowy"));
80 //// Motor mount selection
82 JLabel label = new JLabel("<html><b>Motor mounts:</b>");
83 panel.add(label, "gapbottom para");
85 label = new JLabel("<html>Select which components function as motor mounts:");
86 panel.add(label,"ay 100%, w 1px, growx");
89 JTable table = new JTable(new MotorMountTableModel());
90 table.setTableHeader(null);
91 table.setShowVerticalLines(false);
92 table.setRowSelectionAllowed(false);
93 table.setColumnSelectionAllowed(false);
95 TableColumnModel columnModel = table.getColumnModel();
96 TableColumn col0 = columnModel.getColumn(0);
97 int w = table.getRowHeight() + 2;
99 col0.setPreferredWidth(w);
102 JScrollPane scroll = new JScrollPane(table);
103 panel.add(scroll, "w 200lp, h 150lp, grow, wrap 20lp");
111 label = new JLabel("<html><b>Motor configurations:</b>");
112 panel.add(label, "spanx, gapbottom para");
115 label = new JLabel("Configuration name:");
116 String tip = "Leave name empty for default.";
117 label.setToolTipText(tip);
118 panel.add(label, "");
120 configurationNameField = new JTextField(10);
121 configurationNameField.setToolTipText(tip);
122 configurationNameField.getDocument().addDocumentListener(new DocumentListener() {
124 public void changedUpdate(DocumentEvent e) {
128 public void insertUpdate(DocumentEvent e) {
132 public void removeUpdate(DocumentEvent e) {
135 private void update() {
136 String text = configurationNameField.getText();
137 if (currentID != null) {
138 rocket.setMotorConfigurationName(currentID, text);
139 int row = configurationTable.getSelectedRow();
140 configurationTableModel.fireTableCellUpdated(row, 0);
145 panel.add(configurationNameField, "cell 2 1, gapright para");
147 newConfButton = new JButton("New configuration");
148 newConfButton.addActionListener(new ActionListener() {
150 public void actionPerformed(ActionEvent e) {
151 String id = rocket.newMotorConfigurationID();
152 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
153 configurationTableModel.fireTableDataChanged();
157 panel.add(newConfButton, "cell 3 1");
159 removeConfButton = new JButton("Remove configuration");
160 removeConfButton.addActionListener(new ActionListener() {
162 public void actionPerformed(ActionEvent e) {
163 if (currentID == null)
165 rocket.removeMotorConfigurationID(currentID);
166 rocket.getDefaultConfiguration().setMotorConfigurationID(null);
167 configurationTableModel.fireTableDataChanged();
171 panel.add(removeConfButton, "cell 4 1");
176 configurationTableModel = new MotorConfigurationTableModel();
177 configurationTable = new JTable(configurationTableModel);
178 configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
179 configurationTable.setCellSelectionEnabled(true);
181 configurationTable.addMouseListener(new MouseAdapter() {
183 public void mouseClicked(MouseEvent e) {
185 if (e.getClickCount() == 1) {
187 // Single click updates selection
190 } else if (e.getClickCount() == 2) {
192 // Double-click edits motor
201 scroll = new JScrollPane(configurationTable);
202 panel.add(scroll, "cell 1 2, spanx, w 500lp, h 150lp, grow");
205 selectMotorButton = new JButton("Select motor");
206 selectMotorButton.addActionListener(new ActionListener() {
208 public void actionPerformed(ActionEvent e) {
212 panel.add(selectMotorButton, "spanx, flowx, split 2, ax 50%");
215 removeMotorButton = new JButton("Remove motor");
216 removeMotorButton.addActionListener(new ActionListener() {
218 public void actionPerformed(ActionEvent e) {
222 panel.add(removeMotorButton, "ax 50%");
228 JButton close = new JButton("Close");
229 close.addActionListener(new ActionListener() {
231 public void actionPerformed(ActionEvent e) {
232 EditMotorConfigurationDialog.this.dispose();
235 panel.add(close, "spanx, right");
243 GUIUtil.installEscapeCloseOperation(this);
244 GUIUtil.setDefaultButton(close);
247 final OpenRocketDocument document = BasicFrame.findDocument(rocket);
248 if (document != null) {
249 document.startUndo("Edit motor configurations");
250 this.addWindowListener(new WindowAdapter() {
252 public void windowClosed(WindowEvent e) {
262 private void updateEnabled() {
263 int column = configurationTable.getSelectedColumn();
264 int row = configurationTable.getSelectedRow();
266 if (column < 0 || row < 0) {
271 currentID = findID(row);
275 currentMount = findMount(column);
277 rocket.getDefaultConfiguration().setMotorConfigurationID(currentID);
281 configurationNameField.setEnabled(currentID != null);
282 if (currentID == null) {
283 configurationNameField.setText("");
285 configurationNameField.setText(rocket.getMotorConfigurationName(currentID));
287 removeConfButton.setEnabled(currentID != null);
288 selectMotorButton.setEnabled(currentMount != null && currentID != null);
289 removeMotorButton.setEnabled(currentMount != null && currentID != null);
295 private void selectMotor() {
296 if (currentID == null || currentMount == null)
299 MotorChooserDialog dialog = new MotorChooserDialog(currentMount.getMotor(currentID),
300 currentMount.getMotorDelay(currentID), currentMount.getMotorMountDiameter());
301 dialog.setVisible(true);
302 Motor m = dialog.getSelectedMotor();
303 double d = dialog.getSelectedDelay();
306 currentMount.setMotor(currentID, m);
307 currentMount.setMotorDelay(currentID, d);
310 int row = configurationTable.getSelectedRow();
311 configurationTableModel.fireTableRowsUpdated(row, row);
316 private void removeMotor() {
317 if (currentID == null || currentMount == null)
320 currentMount.setMotor(currentID, null);
322 int row = configurationTable.getSelectedRow();
323 configurationTableModel.fireTableRowsUpdated(row, row);
328 private String findID(int row) {
329 return rocket.getMotorConfigurationIDs()[row+1];
333 private MotorMount findMount(int column) {
334 MotorMount mount = null;
337 for (MotorMount m: mounts) {
338 if (m.isMotorMount())
347 throw new IndexOutOfBoundsException("motor mount not found, column="+column);
354 * The table model for selecting whether components are motor mounts or not.
356 private class MotorMountTableModel extends AbstractTableModel {
359 public int getColumnCount() {
364 public int getRowCount() {
365 return mounts.length;
369 public Class<?> getColumnClass(int column) {
372 return Boolean.class;
378 throw new IndexOutOfBoundsException("column="+column);
383 public Object getValueAt(int row, int column) {
386 return new Boolean(mounts[row].isMotorMount());
389 return mounts[row].toString();
392 throw new IndexOutOfBoundsException("column="+column);
397 public boolean isCellEditable(int row, int column) {
402 public void setValueAt(Object value, int row, int column) {
403 if (column != 0 || !(value instanceof Boolean)) {
404 throw new IllegalArgumentException("column="+column+", value="+value);
407 mounts[row].setMotorMount((Boolean)value);
408 configurationTableModel.fireTableStructureChanged();
416 * The table model for selecting and editing the motor configurations.
418 private class MotorConfigurationTableModel extends AbstractTableModel {
421 public int getColumnCount() {
423 for (MotorMount m: mounts) {
424 if (m.isMotorMount())
431 public int getRowCount() {
432 return rocket.getMotorConfigurationIDs().length-1;
436 public Object getValueAt(int row, int column) {
438 String id = findID(row);
441 return rocket.getMotorConfigurationNameOrDescription(id);
444 MotorMount mount = findMount(column);
445 Motor motor = mount.getMotor(id);
449 String str = motor.getDesignation(mount.getMotorDelay(id));
450 int count = mount.getMotorCount();
452 str = "" + count + "\u00d7 " + str;
459 public String getColumnName(int column) {
461 return "Configuration name";
464 MotorMount mount = findMount(column);
465 String name = mount.toString();
466 int count = mount.getMotorCount();
468 name = name + " (\u00d7" + count + ")";