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.dialogs.motor.MotorChooserDialog;
30 import net.sf.openrocket.gui.main.BasicFrame;
31 import net.sf.openrocket.motor.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.Chars;
36 import net.sf.openrocket.util.GUIUtil;
38 public class EditMotorConfigurationDialog extends JDialog {
40 private final Rocket rocket;
42 private final MotorMount[] mounts;
44 private final JTable configurationTable;
45 private final MotorConfigurationTableModel configurationTableModel;
48 private final JButton newConfButton, removeConfButton;
49 private final JButton selectMotorButton, removeMotorButton;
50 private final JTextField configurationNameField;
53 private String currentID = null;
54 private MotorMount currentMount = null;
56 // Positive when user is modifying configuration name
57 private int configurationNameModification = 0;
59 public EditMotorConfigurationDialog(final Rocket rocket, Window parent) {
60 super(parent, "Edit motor configurations");
63 this.setModalityType(ModalityType.DOCUMENT_MODAL);
65 this.setModalityType(ModalityType.APPLICATION_MODAL);
69 ArrayList<MotorMount> mountList = new ArrayList<MotorMount>();
70 Iterator<RocketComponent> iterator = rocket.iterator();
71 while (iterator.hasNext()) {
72 RocketComponent c = iterator.next();
73 if (c instanceof MotorMount) {
74 mountList.add((MotorMount) c);
77 mounts = mountList.toArray(new MotorMount[0]);
81 JPanel panel = new JPanel(new MigLayout("fill, flowy"));
84 //// Motor mount selection
86 JLabel label = new JLabel("<html><b>Motor mounts:</b>");
87 panel.add(label, "gapbottom para");
89 label = new JLabel("<html>Select which components function as motor mounts:");
90 panel.add(label, "ay 100%, w 1px, growx");
93 JTable table = new JTable(new MotorMountTableModel());
94 table.setTableHeader(null);
95 table.setShowVerticalLines(false);
96 table.setRowSelectionAllowed(false);
97 table.setColumnSelectionAllowed(false);
99 TableColumnModel columnModel = table.getColumnModel();
100 TableColumn col0 = columnModel.getColumn(0);
101 int w = table.getRowHeight() + 2;
103 col0.setPreferredWidth(w);
106 table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
108 JScrollPane scroll = new JScrollPane(table);
109 panel.add(scroll, "w 200lp, h 150lp, grow, wrap 20lp");
117 label = new JLabel("<html><b>Motor configurations:</b>");
118 panel.add(label, "spanx, gapbottom para");
121 label = new JLabel("Configuration name:");
122 String tip = "Leave name empty for default.";
123 label.setToolTipText(tip);
124 panel.add(label, "");
126 configurationNameField = new JTextField(10);
127 configurationNameField.setToolTipText(tip);
128 configurationNameField.getDocument().addDocumentListener(new DocumentListener() {
130 public void changedUpdate(DocumentEvent e) {
135 public void insertUpdate(DocumentEvent e) {
140 public void removeUpdate(DocumentEvent e) {
144 private void update() {
145 if (configurationNameModification != 0)
148 String text = configurationNameField.getText();
149 if (currentID != null) {
150 configurationNameModification++;
151 rocket.setMotorConfigurationName(currentID, text);
152 int row = configurationTable.getSelectedRow();
153 configurationTableModel.fireTableCellUpdated(row, 0);
155 configurationNameModification--;
159 panel.add(configurationNameField, "cell 2 1, gapright para");
161 newConfButton = new JButton("New configuration");
162 newConfButton.addActionListener(new ActionListener() {
164 public void actionPerformed(ActionEvent e) {
165 String id = rocket.newMotorConfigurationID();
166 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
167 configurationTableModel.fireTableDataChanged();
171 panel.add(newConfButton, "cell 3 1");
173 removeConfButton = new JButton("Remove configuration");
174 removeConfButton.addActionListener(new ActionListener() {
176 public void actionPerformed(ActionEvent e) {
177 if (currentID == null)
179 rocket.removeMotorConfigurationID(currentID);
180 rocket.getDefaultConfiguration().setMotorConfigurationID(null);
181 configurationTableModel.fireTableDataChanged();
185 panel.add(removeConfButton, "cell 4 1");
190 configurationTableModel = new MotorConfigurationTableModel();
191 configurationTable = new JTable(configurationTableModel);
192 configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
193 configurationTable.setCellSelectionEnabled(true);
195 configurationTable.addMouseListener(new MouseAdapter() {
197 public void mouseClicked(MouseEvent e) {
199 if (e.getClickCount() == 1) {
201 // Single click updates selection
204 } else if (e.getClickCount() == 2) {
206 // Double-click edits motor
215 scroll = new JScrollPane(configurationTable);
216 panel.add(scroll, "cell 1 2, spanx, w 500lp, h 150lp, grow");
219 selectMotorButton = new JButton("Select motor");
220 selectMotorButton.addActionListener(new ActionListener() {
222 public void actionPerformed(ActionEvent e) {
226 panel.add(selectMotorButton, "spanx, flowx, split 2, ax 50%");
229 removeMotorButton = new JButton("Remove motor");
230 removeMotorButton.addActionListener(new ActionListener() {
232 public void actionPerformed(ActionEvent e) {
236 panel.add(removeMotorButton, "ax 50%");
242 JButton close = new JButton("Close");
243 close.addActionListener(new ActionListener() {
245 public void actionPerformed(ActionEvent e) {
246 EditMotorConfigurationDialog.this.dispose();
249 panel.add(close, "spanx, right");
257 this.setLocationByPlatform(true);
258 GUIUtil.setDisposableDialogOptions(this, close);
261 final OpenRocketDocument document = BasicFrame.findDocument(rocket);
262 if (document != null) {
263 document.startUndo("Edit motor configurations");
264 this.addWindowListener(new WindowAdapter() {
266 public void windowClosed(WindowEvent e) {
276 private void updateEnabled() {
277 int column = configurationTable.getSelectedColumn();
278 int row = configurationTable.getSelectedRow();
280 if (column < 0 || row < 0) {
285 currentID = findID(row);
289 currentMount = findMount(column);
291 rocket.getDefaultConfiguration().setMotorConfigurationID(currentID);
295 if (configurationNameModification == 0) {
296 // Don't update name field when user is modifying it
297 configurationNameModification++;
299 configurationNameField.setEnabled(currentID != null);
300 if (currentID == null) {
301 configurationNameField.setText("");
303 configurationNameField.setText(rocket.getMotorConfigurationName(currentID));
306 configurationNameModification--;
308 removeConfButton.setEnabled(currentID != null);
309 selectMotorButton.setEnabled(currentMount != null && currentID != null);
310 removeMotorButton.setEnabled(currentMount != null && currentID != null);
316 private void selectMotor() {
317 if (currentID == null || currentMount == null)
320 MotorChooserDialog dialog = new MotorChooserDialog(currentMount.getMotor(currentID),
321 currentMount.getMotorDelay(currentID), currentMount.getMotorMountDiameter(), this);
322 dialog.setVisible(true);
323 Motor m = dialog.getSelectedMotor();
324 double d = dialog.getSelectedDelay();
327 currentMount.setMotor(currentID, m);
328 currentMount.setMotorDelay(currentID, d);
331 int row = configurationTable.getSelectedRow();
332 configurationTableModel.fireTableRowsUpdated(row, row);
337 private void removeMotor() {
338 if (currentID == null || currentMount == null)
341 currentMount.setMotor(currentID, null);
343 int row = configurationTable.getSelectedRow();
344 configurationTableModel.fireTableRowsUpdated(row, row);
349 private String findID(int row) {
350 return rocket.getMotorConfigurationIDs()[row + 1];
354 private MotorMount findMount(int column) {
355 MotorMount mount = null;
358 for (MotorMount m : mounts) {
359 if (m.isMotorMount())
368 throw new IndexOutOfBoundsException("motor mount not found, column=" + column);
375 * The table model for selecting whether components are motor mounts or not.
377 private class MotorMountTableModel extends AbstractTableModel {
380 public int getColumnCount() {
385 public int getRowCount() {
386 return mounts.length;
390 public Class<?> getColumnClass(int column) {
393 return Boolean.class;
399 throw new IndexOutOfBoundsException("column=" + column);
404 public Object getValueAt(int row, int column) {
407 return new Boolean(mounts[row].isMotorMount());
410 return mounts[row].toString();
413 throw new IndexOutOfBoundsException("column=" + column);
418 public boolean isCellEditable(int row, int column) {
423 public void setValueAt(Object value, int row, int column) {
424 if (column != 0 || !(value instanceof Boolean)) {
425 throw new IllegalArgumentException("column=" + column + ", value=" + value);
428 mounts[row].setMotorMount((Boolean) value);
429 configurationTableModel.fireTableStructureChanged();
437 * The table model for selecting and editing the motor configurations.
439 private class MotorConfigurationTableModel extends AbstractTableModel {
442 public int getColumnCount() {
444 for (MotorMount m : mounts) {
445 if (m.isMotorMount())
452 public int getRowCount() {
453 return rocket.getMotorConfigurationIDs().length - 1;
457 public Object getValueAt(int row, int column) {
459 String id = findID(row);
462 return rocket.getMotorConfigurationNameOrDescription(id);
465 MotorMount mount = findMount(column);
466 Motor motor = mount.getMotor(id);
470 String str = motor.getDesignation(mount.getMotorDelay(id));
471 int count = mount.getMotorCount();
473 str = "" + count + Chars.TIMES + " " + str;
480 public String getColumnName(int column) {
482 return "Configuration name";
485 MotorMount mount = findMount(column);
486 String name = mount.toString();
487 int count = mount.getMotorCount();
489 name = name + " (" + Chars.TIMES + count + ")";