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.gui.util.GUIUtil;
32 import net.sf.openrocket.l10n.Translator;
33 import net.sf.openrocket.motor.Motor;
34 import net.sf.openrocket.rocketcomponent.MotorMount;
35 import net.sf.openrocket.rocketcomponent.Rocket;
36 import net.sf.openrocket.rocketcomponent.RocketComponent;
37 import net.sf.openrocket.startup.Application;
38 import net.sf.openrocket.util.Chars;
40 public class EditMotorConfigurationDialog extends JDialog {
42 private final Rocket rocket;
44 private final MotorMount[] mounts;
46 private final JTable configurationTable;
47 private final MotorConfigurationTableModel configurationTableModel;
50 private final JButton newConfButton, removeConfButton;
51 private final JButton selectMotorButton, removeMotorButton;
52 private final JTextField configurationNameField;
55 private String currentID = null;
56 private MotorMount currentMount = null;
58 // Positive when user is modifying configuration name
59 private int configurationNameModification = 0;
60 private static final Translator trans = Application.getTranslator();
62 public EditMotorConfigurationDialog(final Rocket rocket, Window parent) {
63 //// Edit motor configurations
64 super(parent, trans.get("edtmotorconfdlg.title.Editmotorconf"));
67 this.setModalityType(ModalityType.DOCUMENT_MODAL);
69 this.setModalityType(ModalityType.APPLICATION_MODAL);
73 ArrayList<MotorMount> mountList = new ArrayList<MotorMount>();
74 Iterator<RocketComponent> iterator = rocket.iterator();
75 while (iterator.hasNext()) {
76 RocketComponent c = iterator.next();
77 if (c instanceof MotorMount) {
78 mountList.add((MotorMount) c);
81 mounts = mountList.toArray(new MotorMount[0]);
85 JPanel panel = new JPanel(new MigLayout("fill, flowy"));
88 //// Motor mount selection
89 //// <html><b>Motor mounts:</b>
90 JLabel label = new JLabel(trans.get("edtmotorconfdlg.lbl.Motormounts"));
91 panel.add(label, "gapbottom para");
93 //// <html>Select which components function as motor mounts:
94 label = new JLabel(trans.get("edtmotorconfdlg.selectcomp"));
95 panel.add(label, "ay 100%, w 1px, growx");
98 JTable table = new JTable(new MotorMountTableModel());
99 table.setTableHeader(null);
100 table.setShowVerticalLines(false);
101 table.setRowSelectionAllowed(false);
102 table.setColumnSelectionAllowed(false);
104 TableColumnModel columnModel = table.getColumnModel();
105 TableColumn col0 = columnModel.getColumn(0);
106 int w = table.getRowHeight() + 2;
108 col0.setPreferredWidth(w);
111 table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
113 JScrollPane scroll = new JScrollPane(table);
114 panel.add(scroll, "w 200lp, h 150lp, grow, wrap 20lp");
121 //// <html><b>Motor configurations:</b>
122 label = new JLabel(trans.get("edtmotorconfdlg.lbl.Motorconfig"));
123 panel.add(label, "spanx, gapbottom para");
125 //// Configuration name:
126 label = new JLabel(trans.get("edtmotorconfdlg.lbl.Configname"));
127 //// Leave name empty for default.
128 String tip = trans.get("edtmotorconfdlg.lbl.Leavenamedefault");
129 label.setToolTipText(tip);
130 panel.add(label, "");
132 configurationNameField = new JTextField(10);
133 configurationNameField.setToolTipText(tip);
134 configurationNameField.getDocument().addDocumentListener(new DocumentListener() {
136 public void changedUpdate(DocumentEvent e) {
141 public void insertUpdate(DocumentEvent e) {
146 public void removeUpdate(DocumentEvent e) {
150 private void update() {
151 if (configurationNameModification != 0)
154 String text = configurationNameField.getText();
155 if (currentID != null) {
156 configurationNameModification++;
157 rocket.setMotorConfigurationName(currentID, text);
158 int row = configurationTable.getSelectedRow();
159 configurationTableModel.fireTableCellUpdated(row, 0);
161 configurationNameModification--;
165 panel.add(configurationNameField, "cell 2 1, gapright para");
167 //// New configuration
168 newConfButton = new JButton(trans.get("edtmotorconfdlg.but.Newconfiguration"));
169 newConfButton.addActionListener(new ActionListener() {
171 public void actionPerformed(ActionEvent e) {
172 String id = rocket.newMotorConfigurationID();
173 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
174 configurationTableModel.fireTableDataChanged();
178 panel.add(newConfButton, "cell 3 1");
180 //// Remove configuration
181 removeConfButton = new JButton(trans.get("edtmotorconfdlg.but.Removeconfiguration"));
182 removeConfButton.addActionListener(new ActionListener() {
184 public void actionPerformed(ActionEvent e) {
185 if (currentID == null)
187 rocket.removeMotorConfigurationID(currentID);
188 rocket.getDefaultConfiguration().setMotorConfigurationID(null);
189 configurationTableModel.fireTableDataChanged();
193 panel.add(removeConfButton, "cell 4 1");
198 configurationTableModel = new MotorConfigurationTableModel();
199 configurationTable = new JTable(configurationTableModel);
200 configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
201 configurationTable.setCellSelectionEnabled(true);
203 configurationTable.addMouseListener(new MouseAdapter() {
205 public void mouseClicked(MouseEvent e) {
207 if (e.getClickCount() == 1) {
209 // Single click updates selection
212 } else if (e.getClickCount() == 2) {
214 // Double-click edits motor
223 scroll = new JScrollPane(configurationTable);
224 panel.add(scroll, "cell 1 2, spanx, w 500lp, h 150lp, grow");
227 selectMotorButton = new JButton(trans.get("edtmotorconfdlg.but.Selectmotor"));
228 selectMotorButton.addActionListener(new ActionListener() {
230 public void actionPerformed(ActionEvent e) {
234 panel.add(selectMotorButton, "spanx, flowx, split 2, ax 50%");
236 //// Remove motor button
237 removeMotorButton = new JButton(trans.get("edtmotorconfdlg.but.removemotor"));
238 removeMotorButton.addActionListener(new ActionListener() {
240 public void actionPerformed(ActionEvent e) {
244 panel.add(removeMotorButton, "ax 50%");
249 JButton close = new JButton(trans.get("dlg.but.close"));
250 close.addActionListener(new ActionListener() {
252 public void actionPerformed(ActionEvent e) {
253 EditMotorConfigurationDialog.this.dispose();
256 panel.add(close, "spanx, right");
264 this.setLocationByPlatform(true);
265 GUIUtil.setDisposableDialogOptions(this, close);
268 final OpenRocketDocument document = BasicFrame.findDocument(rocket);
269 if (document != null) {
270 //// Edit motor configurations
271 document.startUndo(trans.get("edtmotorconfdlg.title.Editmotorconf"));
272 this.addWindowListener(new WindowAdapter() {
274 public void windowClosed(WindowEvent e) {
284 private void updateEnabled() {
285 int column = configurationTable.getSelectedColumn();
286 int row = configurationTable.getSelectedRow();
288 if (column < 0 || row < 0) {
293 currentID = findID(row);
297 currentMount = findMount(column);
299 rocket.getDefaultConfiguration().setMotorConfigurationID(currentID);
303 if (configurationNameModification == 0) {
304 // Don't update name field when user is modifying it
305 configurationNameModification++;
307 configurationNameField.setEnabled(currentID != null);
308 if (currentID == null) {
309 configurationNameField.setText("");
311 configurationNameField.setText(rocket.getMotorConfigurationName(currentID));
314 configurationNameModification--;
316 removeConfButton.setEnabled(currentID != null);
317 selectMotorButton.setEnabled(currentMount != null && currentID != null);
318 removeMotorButton.setEnabled(currentMount != null && currentID != null);
324 private void selectMotor() {
325 if (currentID == null || currentMount == null)
328 MotorChooserDialog dialog = new MotorChooserDialog(currentMount.getMotor(currentID),
329 currentMount.getMotorDelay(currentID), currentMount.getMotorMountDiameter(), this);
330 dialog.setVisible(true);
331 Motor m = dialog.getSelectedMotor();
332 double d = dialog.getSelectedDelay();
335 currentMount.setMotor(currentID, m);
336 currentMount.setMotorDelay(currentID, d);
339 int row = configurationTable.getSelectedRow();
340 configurationTableModel.fireTableRowsUpdated(row, row);
345 private void removeMotor() {
346 if (currentID == null || currentMount == null)
349 currentMount.setMotor(currentID, null);
351 int row = configurationTable.getSelectedRow();
352 configurationTableModel.fireTableRowsUpdated(row, row);
357 private String findID(int row) {
358 return rocket.getMotorConfigurationIDs()[row + 1];
362 private MotorMount findMount(int column) {
363 MotorMount mount = null;
366 for (MotorMount m : mounts) {
367 if (m.isMotorMount())
376 throw new IndexOutOfBoundsException("motor mount not found, column=" + column);
383 * The table model for selecting whether components are motor mounts or not.
385 private class MotorMountTableModel extends AbstractTableModel {
388 public int getColumnCount() {
393 public int getRowCount() {
394 return mounts.length;
398 public Class<?> getColumnClass(int column) {
401 return Boolean.class;
407 throw new IndexOutOfBoundsException("column=" + column);
412 public Object getValueAt(int row, int column) {
415 return new Boolean(mounts[row].isMotorMount());
418 return mounts[row].toString();
421 throw new IndexOutOfBoundsException("column=" + column);
426 public boolean isCellEditable(int row, int column) {
431 public void setValueAt(Object value, int row, int column) {
432 if (column != 0 || !(value instanceof Boolean)) {
433 throw new IllegalArgumentException("column=" + column + ", value=" + value);
436 mounts[row].setMotorMount((Boolean) value);
437 configurationTableModel.fireTableStructureChanged();
445 * The table model for selecting and editing the motor configurations.
447 private class MotorConfigurationTableModel extends AbstractTableModel {
450 public int getColumnCount() {
452 for (MotorMount m : mounts) {
453 if (m.isMotorMount())
460 public int getRowCount() {
461 return rocket.getMotorConfigurationIDs().length - 1;
465 public Object getValueAt(int row, int column) {
467 String id = findID(row);
470 return rocket.getMotorConfigurationNameOrDescription(id);
473 MotorMount mount = findMount(column);
474 Motor motor = mount.getMotor(id);
479 String str = motor.getDesignation(mount.getMotorDelay(id));
480 int count = mount.getMotorCount();
482 str = "" + count + Chars.TIMES + " " + str;
489 public String getColumnName(int column) {
491 //// Configuration name
492 return trans.get("edtmotorconfdlg.lbl.Configname");
495 MotorMount mount = findMount(column);
496 String name = mount.toString();
497 int count = mount.getMotorCount();
499 name = name + " (" + Chars.TIMES + count + ")";