added svn:ignores
[debian/openrocket] / src / net / sf / openrocket / gui / dialogs / EditMotorConfigurationDialog.java
1 package net.sf.openrocket.gui.dialogs;
2
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;
12
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;
26
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;
37
38 public class EditMotorConfigurationDialog extends JDialog {
39         
40         private final Rocket rocket;
41         
42         private final MotorMount[] mounts;
43         
44         private final JTable configurationTable;
45         private final MotorConfigurationTableModel configurationTableModel;
46         
47
48         private final JButton newConfButton, removeConfButton;
49         private final JButton selectMotorButton, removeMotorButton;
50         private final JTextField configurationNameField;
51         
52
53         private String currentID = null;
54         private MotorMount currentMount = null;
55         
56         // Positive when user is modifying configuration name
57         private int configurationNameModification = 0;
58         
59         public EditMotorConfigurationDialog(final Rocket rocket, Window parent) {
60                 super(parent, "Edit motor configurations");
61                 
62                 if (parent != null)
63                         this.setModalityType(ModalityType.DOCUMENT_MODAL);
64                 else
65                         this.setModalityType(ModalityType.APPLICATION_MODAL);
66                 
67                 this.rocket = rocket;
68                 
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);
75                         }
76                 }
77                 mounts = mountList.toArray(new MotorMount[0]);
78                 
79
80
81                 JPanel panel = new JPanel(new MigLayout("fill, flowy"));
82                 
83
84                 ////  Motor mount selection
85                 
86                 JLabel label = new JLabel("<html><b>Motor mounts:</b>");
87                 panel.add(label, "gapbottom para");
88                 
89                 label = new JLabel("<html>Select which components function as motor mounts:");
90                 panel.add(label, "ay 100%, w 1px, growx");
91                 
92
93                 JTable table = new JTable(new MotorMountTableModel());
94                 table.setTableHeader(null);
95                 table.setShowVerticalLines(false);
96                 table.setRowSelectionAllowed(false);
97                 table.setColumnSelectionAllowed(false);
98                 
99                 TableColumnModel columnModel = table.getColumnModel();
100                 TableColumn col0 = columnModel.getColumn(0);
101                 int w = table.getRowHeight() + 2;
102                 col0.setMinWidth(w);
103                 col0.setPreferredWidth(w);
104                 col0.setMaxWidth(w);
105                 
106                 table.addMouseListener(new GUIUtil.BooleanTableClickListener(table));
107                 
108                 JScrollPane scroll = new JScrollPane(table);
109                 panel.add(scroll, "w 200lp, h 150lp, grow, wrap 20lp");
110                 
111
112
113
114
115                 //// Motor selection
116                 
117                 label = new JLabel("<html><b>Motor configurations:</b>");
118                 panel.add(label, "spanx, gapbottom para");
119                 
120
121                 label = new JLabel("Configuration name:");
122                 String tip = "Leave name empty for default.";
123                 label.setToolTipText(tip);
124                 panel.add(label, "");
125                 
126                 configurationNameField = new JTextField(10);
127                 configurationNameField.setToolTipText(tip);
128                 configurationNameField.getDocument().addDocumentListener(new DocumentListener() {
129                         @Override
130                         public void changedUpdate(DocumentEvent e) {
131                                 update();
132                         }
133                         
134                         @Override
135                         public void insertUpdate(DocumentEvent e) {
136                                 update();
137                         }
138                         
139                         @Override
140                         public void removeUpdate(DocumentEvent e) {
141                                 update();
142                         }
143                         
144                         private void update() {
145                                 if (configurationNameModification != 0)
146                                         return;
147                                 
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);
154                                         updateEnabled();
155                                         configurationNameModification--;
156                                 }
157                         }
158                 });
159                 panel.add(configurationNameField, "cell 2 1, gapright para");
160                 
161                 newConfButton = new JButton("New configuration");
162                 newConfButton.addActionListener(new ActionListener() {
163                         @Override
164                         public void actionPerformed(ActionEvent e) {
165                                 String id = rocket.newMotorConfigurationID();
166                                 rocket.getDefaultConfiguration().setMotorConfigurationID(id);
167                                 configurationTableModel.fireTableDataChanged();
168                                 updateEnabled();
169                         }
170                 });
171                 panel.add(newConfButton, "cell 3 1");
172                 
173                 removeConfButton = new JButton("Remove configuration");
174                 removeConfButton.addActionListener(new ActionListener() {
175                         @Override
176                         public void actionPerformed(ActionEvent e) {
177                                 if (currentID == null)
178                                         return;
179                                 rocket.removeMotorConfigurationID(currentID);
180                                 rocket.getDefaultConfiguration().setMotorConfigurationID(null);
181                                 configurationTableModel.fireTableDataChanged();
182                                 updateEnabled();
183                         }
184                 });
185                 panel.add(removeConfButton, "cell 4 1");
186                 
187
188
189
190                 configurationTableModel = new MotorConfigurationTableModel();
191                 configurationTable = new JTable(configurationTableModel);
192                 configurationTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
193                 configurationTable.setCellSelectionEnabled(true);
194                 
195                 configurationTable.addMouseListener(new MouseAdapter() {
196                         @Override
197                         public void mouseClicked(MouseEvent e) {
198                                 
199                                 if (e.getClickCount() == 1) {
200                                         
201                                         // Single click updates selection
202                                         updateEnabled();
203                                         
204                                 } else if (e.getClickCount() == 2) {
205                                         
206                                         // Double-click edits motor
207                                         selectMotor();
208                                         
209                                 }
210                                 
211                         }
212                 });
213                 
214
215                 scroll = new JScrollPane(configurationTable);
216                 panel.add(scroll, "cell 1 2, spanx, w 500lp, h 150lp, grow");
217                 
218
219                 selectMotorButton = new JButton("Select motor");
220                 selectMotorButton.addActionListener(new ActionListener() {
221                         @Override
222                         public void actionPerformed(ActionEvent e) {
223                                 selectMotor();
224                         }
225                 });
226                 panel.add(selectMotorButton, "spanx, flowx, split 2, ax 50%");
227                 
228
229                 removeMotorButton = new JButton("Remove motor");
230                 removeMotorButton.addActionListener(new ActionListener() {
231                         @Override
232                         public void actionPerformed(ActionEvent e) {
233                                 removeMotor();
234                         }
235                 });
236                 panel.add(removeMotorButton, "ax 50%");
237                 
238
239
240                 //// Close button
241                 
242                 JButton close = new JButton("Close");
243                 close.addActionListener(new ActionListener() {
244                         @Override
245                         public void actionPerformed(ActionEvent e) {
246                                 EditMotorConfigurationDialog.this.dispose();
247                         }
248                 });
249                 panel.add(close, "spanx, right");
250                 
251                 this.add(panel);
252                 this.validate();
253                 this.pack();
254                 
255                 updateEnabled();
256                 
257                 this.setLocationByPlatform(true);
258                 GUIUtil.setDisposableDialogOptions(this, close);
259                 
260                 // Undo description
261                 final OpenRocketDocument document = BasicFrame.findDocument(rocket);
262                 if (document != null) {
263                         document.startUndo("Edit motor configurations");
264                         this.addWindowListener(new WindowAdapter() {
265                                 @Override
266                                 public void windowClosed(WindowEvent e) {
267                                         document.stopUndo();
268                                 }
269                         });
270                 }
271         }
272         
273         
274
275
276         private void updateEnabled() {
277                 int column = configurationTable.getSelectedColumn();
278                 int row = configurationTable.getSelectedRow();
279                 
280                 if (column < 0 || row < 0) {
281                         currentID = null;
282                         currentMount = null;
283                 } else {
284                         
285                         currentID = findID(row);
286                         if (column == 0) {
287                                 currentMount = null;
288                         } else {
289                                 currentMount = findMount(column);
290                         }
291                         rocket.getDefaultConfiguration().setMotorConfigurationID(currentID);
292                         
293                 }
294                 
295                 if (configurationNameModification == 0) {
296                         // Don't update name field when user is modifying it
297                         configurationNameModification++;
298                         
299                         configurationNameField.setEnabled(currentID != null);
300                         if (currentID == null) {
301                                 configurationNameField.setText("");
302                         } else {
303                                 configurationNameField.setText(rocket.getMotorConfigurationName(currentID));
304                         }
305                         
306                         configurationNameModification--;
307                 }
308                 removeConfButton.setEnabled(currentID != null);
309                 selectMotorButton.setEnabled(currentMount != null && currentID != null);
310                 removeMotorButton.setEnabled(currentMount != null && currentID != null);
311         }
312         
313         
314
315
316         private void selectMotor() {
317                 if (currentID == null || currentMount == null)
318                         return;
319                 
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();
325                 
326                 if (m != null) {
327                         currentMount.setMotor(currentID, m);
328                         currentMount.setMotorDelay(currentID, d);
329                 }
330                 
331                 int row = configurationTable.getSelectedRow();
332                 configurationTableModel.fireTableRowsUpdated(row, row);
333                 updateEnabled();
334         }
335         
336         
337         private void removeMotor() {
338                 if (currentID == null || currentMount == null)
339                         return;
340                 
341                 currentMount.setMotor(currentID, null);
342                 
343                 int row = configurationTable.getSelectedRow();
344                 configurationTableModel.fireTableRowsUpdated(row, row);
345                 updateEnabled();
346         }
347         
348         
349         private String findID(int row) {
350                 return rocket.getMotorConfigurationIDs()[row + 1];
351         }
352         
353         
354         private MotorMount findMount(int column) {
355                 MotorMount mount = null;
356                 
357                 int count = column;
358                 for (MotorMount m : mounts) {
359                         if (m.isMotorMount())
360                                 count--;
361                         if (count <= 0) {
362                                 mount = m;
363                                 break;
364                         }
365                 }
366                 
367                 if (mount == null) {
368                         throw new IndexOutOfBoundsException("motor mount not found, column=" + column);
369                 }
370                 return mount;
371         }
372         
373         
374         /**
375          * The table model for selecting whether components are motor mounts or not.
376          */
377         private class MotorMountTableModel extends AbstractTableModel {
378                 
379                 @Override
380                 public int getColumnCount() {
381                         return 2;
382                 }
383                 
384                 @Override
385                 public int getRowCount() {
386                         return mounts.length;
387                 }
388                 
389                 @Override
390                 public Class<?> getColumnClass(int column) {
391                         switch (column) {
392                         case 0:
393                                 return Boolean.class;
394                                 
395                         case 1:
396                                 return String.class;
397                                 
398                         default:
399                                 throw new IndexOutOfBoundsException("column=" + column);
400                         }
401                 }
402                 
403                 @Override
404                 public Object getValueAt(int row, int column) {
405                         switch (column) {
406                         case 0:
407                                 return new Boolean(mounts[row].isMotorMount());
408                                 
409                         case 1:
410                                 return mounts[row].toString();
411                                 
412                         default:
413                                 throw new IndexOutOfBoundsException("column=" + column);
414                         }
415                 }
416                 
417                 @Override
418                 public boolean isCellEditable(int row, int column) {
419                         return column == 0;
420                 }
421                 
422                 @Override
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);
426                         }
427                         
428                         mounts[row].setMotorMount((Boolean) value);
429                         configurationTableModel.fireTableStructureChanged();
430                         updateEnabled();
431                 }
432         }
433         
434         
435
436         /**
437          * The table model for selecting and editing the motor configurations.
438          */
439         private class MotorConfigurationTableModel extends AbstractTableModel {
440                 
441                 @Override
442                 public int getColumnCount() {
443                         int count = 1;
444                         for (MotorMount m : mounts) {
445                                 if (m.isMotorMount())
446                                         count++;
447                         }
448                         return count;
449                 }
450                 
451                 @Override
452                 public int getRowCount() {
453                         return rocket.getMotorConfigurationIDs().length - 1;
454                 }
455                 
456                 @Override
457                 public Object getValueAt(int row, int column) {
458                         
459                         String id = findID(row);
460                         
461                         if (column == 0) {
462                                 return rocket.getMotorConfigurationNameOrDescription(id);
463                         }
464                         
465                         MotorMount mount = findMount(column);
466                         Motor motor = mount.getMotor(id);
467                         if (motor == null)
468                                 return "None";
469                         
470                         String str = motor.getDesignation(mount.getMotorDelay(id));
471                         int count = mount.getMotorCount();
472                         if (count > 1) {
473                                 str = "" + count + Chars.TIMES + " " + str;
474                         }
475                         return str;
476                 }
477                 
478                 
479                 @Override
480                 public String getColumnName(int column) {
481                         if (column == 0) {
482                                 return "Configuration name";
483                         }
484                         
485                         MotorMount mount = findMount(column);
486                         String name = mount.toString();
487                         int count = mount.getMotorCount();
488                         if (count > 1) {
489                                 name = name + " (" + Chars.TIMES + count + ")";
490                         }
491                         return name;
492                 }
493                 
494         }
495         
496 }