create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / preset / PresetEditorDialog.java
1 package net.sf.openrocket.gui.preset;
2
3 import java.awt.BorderLayout;
4 import java.awt.CardLayout;
5 import java.awt.Dimension;
6 import java.awt.Graphics2D;
7 import java.awt.Image;
8 import java.awt.Rectangle;
9 import java.awt.event.ActionEvent;
10 import java.awt.event.ActionListener;
11 import java.awt.event.ItemEvent;
12 import java.awt.event.ItemListener;
13 import java.awt.event.MouseAdapter;
14 import java.awt.event.MouseEvent;
15 import java.awt.image.BufferedImage;
16 import java.io.ByteArrayInputStream;
17 import java.io.ByteArrayOutputStream;
18 import java.io.File;
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.HashMap;
22 import java.util.List;
23 import java.util.Map;
24 import java.util.regex.Matcher;
25 import java.util.regex.Pattern;
26
27 import javax.imageio.ImageIO;
28 import javax.swing.ComboBoxModel;
29 import javax.swing.DefaultComboBoxModel;
30 import javax.swing.ImageIcon;
31 import javax.swing.InputVerifier;
32 import javax.swing.JButton;
33 import javax.swing.JCheckBox;
34 import javax.swing.JComboBox;
35 import javax.swing.JComponent;
36 import javax.swing.JDialog;
37 import javax.swing.JFileChooser;
38 import javax.swing.JLabel;
39 import javax.swing.JOptionPane;
40 import javax.swing.JPanel;
41 import javax.swing.JSpinner;
42 import javax.swing.JTextField;
43 import javax.swing.border.EmptyBorder;
44 import javax.swing.filechooser.FileNameExtensionFilter;
45 import javax.swing.text.JTextComponent;
46
47 import net.miginfocom.swing.MigLayout;
48 import net.sf.openrocket.gui.SpinnerEditor;
49 import net.sf.openrocket.gui.adaptors.DoubleModel;
50 import net.sf.openrocket.gui.components.UnitSelector;
51 import net.sf.openrocket.l10n.Translator;
52 import net.sf.openrocket.logging.LogHelper;
53 import net.sf.openrocket.material.Material;
54 import net.sf.openrocket.motor.Manufacturer;
55 import net.sf.openrocket.preset.ComponentPreset;
56 import net.sf.openrocket.preset.ComponentPresetFactory;
57 import net.sf.openrocket.preset.InvalidComponentPresetException;
58 import net.sf.openrocket.preset.TypedKey;
59 import net.sf.openrocket.preset.TypedPropertyMap;
60 import net.sf.openrocket.preset.loader.MaterialHolder;
61 import net.sf.openrocket.rocketcomponent.Transition;
62 import net.sf.openrocket.startup.Application;
63 import net.sf.openrocket.unit.UnitGroup;
64
65 /**
66  * Preset editor for creating new preset components.
67  */
68 public class PresetEditorDialog extends JDialog implements ItemListener {
69         
70         private static Translator trans = Application.getTranslator();
71         
72         private static LogHelper log = Application.getLogger();
73         
74         private static final String NON_NEGATIVE_INTEGER_FIELD = "(\\d){0,10}";
75         
76         /**
77          * Input of non-negative decimals.
78          */
79         final PresetInputVerifier NON_NEGATIVE_INTEGER = new PresetInputVerifier(Pattern.compile(NON_NEGATIVE_INTEGER_FIELD));
80         
81         private final JPanel contentPanel = new JPanel();
82         private DeselectableComboBox typeCombo;
83         private JTextField mfgTextField;
84         private MaterialChooser materialChooser;
85         private MaterialHolder holder = null;
86         
87         private JTextField ncPartNoTextField;
88         private JTextField ncDescTextField;
89         private DoubleModel ncLength;
90         private JCheckBox ncFilledCB;
91         private JComboBox ncShapeCB;
92         private DoubleModel ncAftDia;
93         private DoubleModel ncAftShoulderDia;
94         private DoubleModel ncAftShoulderLen;
95         private DoubleModel ncMass;
96         private ImageIcon ncImage;
97         private JButton ncImageBtn;
98         
99         private JTextField trPartNoTextField;
100         private JTextField trDescTextField;
101         private DoubleModel trLength;
102         private DoubleModel trAftDia;
103         private DoubleModel trAftShoulderDia;
104         private DoubleModel trAftShoulderLen;
105         private DoubleModel trForeDia;
106         private DoubleModel trForeShoulderDia;
107         private DoubleModel trForeShoulderLen;
108         private DoubleModel trMass;
109         private ImageIcon trImage;
110         private JCheckBox trFilledCB;
111         private JComboBox trShapeCB;
112         private JButton trImageBtn;
113         
114         private JTextField btPartNoTextField;
115         private JTextField btDescTextField;
116         private DoubleModel btMass;
117         private DoubleModel btInnerDia;
118         private DoubleModel btOuterDia;
119         private DoubleModel btLength;
120         private ImageIcon btImage;
121         private JButton btImageBtn;
122         
123         private JTextField tcPartNoTextField;
124         private JTextField tcDescTextField;
125         private DoubleModel tcMass;
126         private DoubleModel tcInnerDia;
127         private DoubleModel tcOuterDia;
128         private DoubleModel tcLength;
129         private ImageIcon tcImage;
130         private JButton tcImageBtn;
131         
132         private JTextField bhPartNoTextField;
133         private JTextField bhDescTextField;
134         private DoubleModel bhOuterDia;
135         private DoubleModel bhLength;
136         private DoubleModel bhMass;
137         private ImageIcon bhImage;
138         private JButton bhImageBtn;
139         
140         private JTextField crPartNoTextField;
141         private JTextField crDescTextField;
142         private DoubleModel crOuterDia;
143         private DoubleModel crInnerDia;
144         private DoubleModel crThickness;
145         private DoubleModel crMass;
146         private ImageIcon crImage;
147         private JButton crImageBtn;
148         
149         private JTextField ebPartNoTextField;
150         private JTextField ebDescTextField;
151         private DoubleModel ebOuterDia;
152         private DoubleModel ebInnerDia;
153         private DoubleModel ebThickness;
154         private DoubleModel ebMass;
155         private ImageIcon ebImage;
156         private JButton ebImageBtn;
157         
158         private JTextField llPartNoTextField;
159         private JTextField llDescTextField;
160         private DoubleModel llOuterDia;
161         private DoubleModel llInnerDia;
162         private DoubleModel llLength;
163         private DoubleModel llMass;
164         private ImageIcon llImage;
165         private JButton llImageBtn;
166         
167         private JTextField stPartNoTextField;
168         private JTextField stDescTextField;
169         private DoubleModel stThickness;
170         private DoubleModel stWidth;
171         private DoubleModel stLength;
172         private DoubleModel stMass;
173         private ImageIcon stImage;
174         private JButton stImageBtn;
175         
176         private JTextField pcPartNoTextField;
177         private JTextField pcDescTextField;
178         private JTextField pcSides;
179         private JTextField pcLineCount;
180         private DoubleModel pcDiameter;
181         private DoubleModel pcLineLength;
182         private MaterialChooser pcLineMaterialChooser;
183         private DoubleModel pcMass;
184         private ImageIcon pcImage;
185         private JButton pcImageBtn;
186         
187         private final JFileChooser imageChooser = createImageChooser();
188         
189         private JPanel componentOverlayPanel;
190         
191         private PresetResultListener resultListener;
192         
193         private static Map<String, String> componentMap = new HashMap<String, String>();
194         
195         private static final String NOSE_CONE_KEY = "NoseCone.NoseCone";
196         private static final String BODY_TUBE_KEY = "BodyTube.BodyTube";
197         private static final String TUBE_COUPLER_KEY = "TubeCoupler.TubeCoupler";
198         private static final String TRANSITION_KEY = "Transition.Transition";
199         private static final String CR_KEY = "ComponentIcons.Centeringring";
200         private static final String BULKHEAD_KEY = "Bulkhead.Bulkhead";
201         private static final String EB_KEY = "ComponentIcons.Engineblock";
202         private static final String LAUNCH_LUG_KEY = "ComponentIcons.Launchlug";
203         private static final String STREAMER_KEY = "ComponentIcons.Streamer";
204         private static final String PARACHUTE_KEY = "ComponentIcons.Parachute";
205         
206         
207         static {
208                 componentMap.put(trans.get(NOSE_CONE_KEY), "NOSECONE");
209                 componentMap.put(trans.get(BODY_TUBE_KEY), "BODYTUBE");
210                 componentMap.put(trans.get(TUBE_COUPLER_KEY), "TUBECOUPLER");
211                 componentMap.put(trans.get(TRANSITION_KEY), "TRANSITION");
212                 componentMap.put(trans.get(CR_KEY), "CENTERINGRING");
213                 componentMap.put(trans.get(BULKHEAD_KEY), "BULKHEAD");
214                 componentMap.put(trans.get(EB_KEY), "ENGINEBLOCK");
215                 componentMap.put(trans.get(LAUNCH_LUG_KEY), "LAUNCHLUG");
216                 componentMap.put(trans.get(PARACHUTE_KEY), "PARACHUTE");
217                 componentMap.put(trans.get(STREAMER_KEY), "STREAMER");
218         }
219         
220         /**
221          * Create the dialog.
222          *
223          * @param theCallback the listener that gets the results of editing the presets
224          */
225         public PresetEditorDialog(PresetResultListener theCallback) {
226                 this(theCallback, null, null);
227         }
228         
229         /**
230          * Create the dialog.
231          *
232          * @param theCallback the listener that gets the results of editing the presets
233          * @param toEdit      the ComponentPreset to be edited; or null if a new one is being added
234          * @param matHolder   the set of materials; if null then use system materials
235          */
236         public PresetEditorDialog(PresetResultListener theCallback, ComponentPreset toEdit, MaterialHolder matHolder) {
237                 resultListener = theCallback;
238                 getContentPane().setMinimumSize(new Dimension(200, 200));
239                 setBounds(100, 100, 825, 610);
240                 getContentPane().setLayout(new BorderLayout());
241                 contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
242                 getContentPane().add(contentPanel, BorderLayout.CENTER);
243                 contentPanel.setLayout(new MigLayout("", "[][grow][94.00,grow][232.0,grow][130.00][grow]", "[][][20.00,grow][grow]"));
244                 JLabel lblManufacturer = new JLabel("Manufacturer:");
245                 contentPanel.add(lblManufacturer, "cell 2 0,alignx left,aligny center");
246                 
247                 mfgTextField = new JTextField();
248                 contentPanel.add(mfgTextField, "cell 3 0,growx");
249                 mfgTextField.setColumns(10);
250                 
251                 JLabel typeLabel = new JLabel("Type:");
252                 contentPanel.add(typeLabel, "cell 2 1,alignx left,aligny center");
253                 
254                 componentOverlayPanel = new JPanel();
255                 contentPanel.add(componentOverlayPanel, "cell 1 3 5 2,grow");
256                 componentOverlayPanel.setLayout(new CardLayout(0, 0));
257                 
258                 typeCombo = new DeselectableComboBox();
259                 typeCombo.addItemListener(this);
260                 typeCombo.setModel(new DefaultComboBoxModel());
261                 setItems(typeCombo, toEdit);
262                 contentPanel.add(typeCombo, "cell 3 1,growx");
263                 
264                 JLabel bhMaterialLabel = new JLabel("Material:");
265                 contentPanel.add(bhMaterialLabel, "cell 2 2, alignx left");
266                 
267                 materialChooser = new MaterialChooser(new MaterialModel(this, Material.Type.BULK));
268                 
269                 contentPanel.add(materialChooser, "cell 3 2,growx");
270                 
271                 {
272                         JPanel ncPanel = new JPanel();
273                         componentOverlayPanel.add(ncPanel, "NOSECONE");
274                         ncPanel.setLayout(new MigLayout("", "[61px][159.00,grow][45.00][109.00,grow][189.00,grow][grow]", "[16px][][][][][]"));
275                         JLabel ncPartNoLabel = new JLabel("Part No:");
276                         ncPanel.add(ncPartNoLabel, "cell 0 0,alignx left,aligny center");
277                         
278                         ncPartNoTextField = new JTextField();
279                         ncPanel.add(ncPartNoTextField, "cell 1 0,growx");
280                         ncPartNoTextField.setColumns(10);
281                         
282                         JLabel ncDescLabel = new JLabel("Description:");
283                         ncPanel.add(ncDescLabel, "cell 3 0,alignx left,aligny center");
284                         
285                         ncDescTextField = new JTextField();
286                         ncPanel.add(ncDescTextField, "cell 4 0,growx");
287                         ncDescTextField.setColumns(10);
288                         
289                         ncFilledCB = new JCheckBox("Filled");
290                         ncPanel.add(ncFilledCB, "cell 1 1");
291                         
292                         JLabel ncMaterialLabel = new JLabel(trans.get("RocketCompCfg.lbl.Componentmaterial"));
293                         ncPanel.add(ncMaterialLabel, "cell 0 1,alignx left");
294                         
295                         JLabel ncMassLabel = new JLabel(trans.get("RocketCompCfg.lbl.Componentmass"));
296                         ncPanel.add(ncMassLabel, "cell 3 1,alignx left");
297                         
298                         ncMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
299                         JSpinner spin = new JSpinner(ncMass.getSpinnerModel());
300                         spin.setEditor(new SpinnerEditor(spin));
301                         ncPanel.add(spin, "cell 4 1, growx");
302                         ncPanel.add(new UnitSelector(ncMass), "growx");
303                         
304                         JLabel ncShapeLabel = new JLabel(trans.get("NoseConeCfg.lbl.Noseconeshape"));
305                         ncPanel.add(ncShapeLabel, "cell 0 2,alignx left");
306                         
307                         ncShapeCB = new JComboBox();
308                         ncShapeCB.setModel(new DefaultComboBoxModel(new String[] { Transition.Shape.OGIVE.getName(), Transition.Shape.CONICAL.getName(), Transition.Shape.PARABOLIC.getName(),
309                                         Transition.Shape.ELLIPSOID.getName(), Transition.Shape.HAACK.getName() }));
310                         ncPanel.add(ncShapeCB, "cell 1 2,growx");
311                         
312                         JLabel ncLengthLabel = new JLabel(trans.get("NoseConeCfg.lbl.Noseconelength"));
313                         ncPanel.add(ncLengthLabel, "cell 3 2,alignx left");
314                         
315                         ncLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
316                         spin = new JSpinner(ncLength.getSpinnerModel());
317                         spin.setEditor(new SpinnerEditor(spin));
318                         ncPanel.add(spin, "cell 4 2, growx");
319                         ncPanel.add(new UnitSelector(ncLength), "growx");
320                         
321                         JLabel ncAftDiaLabel = new JLabel("Aft Dia.:");
322                         ncPanel.add(ncAftDiaLabel, "cell 0 3,alignx left");
323                         
324                         ncAftDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
325                         spin = new JSpinner(ncAftDia.getSpinnerModel());
326                         spin.setEditor(new SpinnerEditor(spin));
327                         ncPanel.add(spin, "cell 1 3, growx");
328                         ncPanel.add(new UnitSelector(ncAftDia), "growx");
329                         
330                         JLabel ncAftShoulderLenLabel = new JLabel("Aft Shoulder Len:");
331                         ncPanel.add(ncAftShoulderLenLabel, "cell 0 4,alignx left");
332                         
333                         ncAftShoulderLen = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
334                         spin = new JSpinner(ncAftShoulderLen.getSpinnerModel());
335                         spin.setEditor(new SpinnerEditor(spin));
336                         ncPanel.add(spin, "cell 1 4, growx");
337                         ncPanel.add(new UnitSelector(ncAftShoulderLen), "growx");
338                         
339                         JLabel ncAftShoulderDiaLabel = new JLabel("Aft Shoulder Dia.:");
340                         ncPanel.add(ncAftShoulderDiaLabel, "cell 0 5,alignx left, aligny top, pad 7 0 0 0");
341                         
342                         ncAftShoulderDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
343                         spin = new JSpinner(ncAftShoulderDia.getSpinnerModel());
344                         spin.setEditor(new SpinnerEditor(spin));
345                         ncPanel.add(spin, "cell 1 5, growx, aligny top");
346                         ncPanel.add(new UnitSelector(ncAftShoulderDia), "growx, aligny top, pad 7 0 0 0");
347                         
348                         JPanel panel = new JPanel();
349                         panel.setMinimumSize(new Dimension(200, 200));
350                         ncPanel.add(panel, "cell 4 3, span 1 3");
351                         panel.setLayout(null);
352                         ncImageBtn = new JButton("No Image");
353                         ncImageBtn.setMaximumSize(new Dimension(75, 75));
354                         ncImageBtn.setMinimumSize(new Dimension(75, 75));
355                         panel.add(ncImageBtn);
356                         ncImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
357                         
358                         ncImageBtn.addActionListener(new ActionListener() {
359                                 @Override
360                                 public void actionPerformed(final ActionEvent e) {
361                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
362                                         
363                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
364                                                 File file = imageChooser.getSelectedFile();
365                                                 ncImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
366                                                 ncImageBtn.setIcon(ncImage);
367                                         }
368                                 }
369                         });
370                         
371                 }
372                 {
373                         JPanel trPanel = new JPanel();
374                         componentOverlayPanel.add(trPanel, "TRANSITION");
375                         trPanel.setLayout(new MigLayout("", "[61px][159.00,grow][45.00][109.00,grow][189.00,grow][grow]", "[16px][][][][][]"));
376                         
377                         JLabel trPartNoLabel = new JLabel("Part No:");
378                         trPanel.add(trPartNoLabel, "cell 0 0,alignx left");
379                         
380                         trPartNoTextField = new JTextField();
381                         trPanel.add(trPartNoTextField, "cell 1 0,growx");
382                         trPartNoTextField.setColumns(10);
383                         
384                         JLabel trDescLabel = new JLabel("Description:");
385                         trPanel.add(trDescLabel, "cell 3 0,alignx left");
386                         
387                         trDescTextField = new JTextField();
388                         trPanel.add(trDescTextField, "cell 4 0,growx");
389                         trDescTextField.setColumns(10);
390                         
391                         trFilledCB = new JCheckBox("Filled");
392                         trPanel.add(trFilledCB, "cell 1 1");
393                         
394                         JLabel trMassLabel = new JLabel("Mass:");
395                         trPanel.add(trMassLabel, "cell 3 1,alignx left");
396                         
397                         trMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
398                         JSpinner spin = new JSpinner(trMass.getSpinnerModel());
399                         spin.setEditor(new SpinnerEditor(spin));
400                         trPanel.add(spin, "cell 4 1, growx");
401                         trPanel.add(new UnitSelector(trMass), "growx");
402                         
403                         JLabel trShapeLabel = new JLabel("Shape:");
404                         trPanel.add(trShapeLabel, "cell 0 2,alignx left");
405                         
406                         trShapeCB = new JComboBox();
407                         trShapeCB.setModel(new DefaultComboBoxModel(new String[] { Transition.Shape.OGIVE.getName(), Transition.Shape.CONICAL.getName(), Transition.Shape.PARABOLIC.getName(),
408                                         Transition.Shape.ELLIPSOID.getName(), Transition.Shape.HAACK.getName() }));
409                         trPanel.add(trShapeCB, "cell 1 2,growx");
410                         
411                         JLabel trLengthLabel = new JLabel("Length:");
412                         trPanel.add(trLengthLabel, "cell 3 2,alignx left");
413                         
414                         trLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
415                         spin = new JSpinner(trLength.getSpinnerModel());
416                         spin.setEditor(new SpinnerEditor(spin));
417                         trPanel.add(spin, "cell 4 2, growx");
418                         trPanel.add(new UnitSelector(trLength), "growx");
419                         
420                         JLabel trAftDiaLabel = new JLabel("Aft Dia.:");
421                         trPanel.add(trAftDiaLabel, "cell 0 3,alignx left");
422                         
423                         trAftDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
424                         spin = new JSpinner(trAftDia.getSpinnerModel());
425                         spin.setEditor(new SpinnerEditor(spin));
426                         trPanel.add(spin, "cell 1 3, growx");
427                         trPanel.add(new UnitSelector(trAftDia), "growx");
428                         
429                         JLabel trForeDiaLabel = new JLabel("Fore Dia.:");
430                         trPanel.add(trForeDiaLabel, "cell 3 3,alignx left");
431                         
432                         trForeDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
433                         spin = new JSpinner(trForeDia.getSpinnerModel());
434                         spin.setEditor(new SpinnerEditor(spin));
435                         trPanel.add(spin, "cell 4 3, growx");
436                         trPanel.add(new UnitSelector(trForeDia), "growx");
437                         
438                         JLabel trAftShouldDiaLabel = new JLabel("Aft Shoulder Dia.:");
439                         trPanel.add(trAftShouldDiaLabel, "cell 0 4,alignx left");
440                         
441                         trAftShoulderDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
442                         spin = new JSpinner(trAftShoulderDia.getSpinnerModel());
443                         spin.setEditor(new SpinnerEditor(spin));
444                         trPanel.add(spin, "cell 1 4, growx");
445                         trPanel.add(new UnitSelector(trAftShoulderDia), "growx");
446                         
447                         JLabel trForeShouldDiaLabel = new JLabel("Fore Shoulder Dia.:");
448                         trPanel.add(trForeShouldDiaLabel, "cell 3 4,alignx left");
449                         
450                         trForeShoulderDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
451                         spin = new JSpinner(trForeShoulderDia.getSpinnerModel());
452                         spin.setEditor(new SpinnerEditor(spin));
453                         trPanel.add(spin, "cell 4 4, growx");
454                         trPanel.add(new UnitSelector(trForeShoulderDia), "growx");
455                         
456                         JLabel trAftShoulderLenLabel = new JLabel("Aft Shoulder Len.:");
457                         trPanel.add(trAftShoulderLenLabel, "cell 0 5,alignx left");
458                         
459                         trAftShoulderLen = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
460                         spin = new JSpinner(trAftShoulderLen.getSpinnerModel());
461                         spin.setEditor(new SpinnerEditor(spin));
462                         trPanel.add(spin, "cell 1 5, growx");
463                         trPanel.add(new UnitSelector(trAftShoulderLen), "growx");
464                         
465                         JLabel lblForeShoulderLen = new JLabel("Fore Shoulder Len.:");
466                         trPanel.add(lblForeShoulderLen, "cell 3 5,alignx left");
467                         
468                         trForeShoulderLen = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0, 2);
469                         spin = new JSpinner(trForeShoulderLen.getSpinnerModel());
470                         spin.setEditor(new SpinnerEditor(spin));
471                         trPanel.add(spin, "cell 4 5, growx");
472                         trPanel.add(new UnitSelector(trForeShoulderLen), "growx");
473                         
474                         JPanel panel = new JPanel();
475                         panel.setMinimumSize(new Dimension(200, 200));
476                         trPanel.add(panel, "cell 4 6");
477                         panel.setLayout(null);
478                         trImageBtn = new JButton("No Image");
479                         trImageBtn.setMaximumSize(new Dimension(75, 75));
480                         trImageBtn.setMinimumSize(new Dimension(75, 75));
481                         panel.add(trImageBtn);
482                         trImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
483                         
484                         trImageBtn.addActionListener(new ActionListener() {
485                                 @Override
486                                 public void actionPerformed(final ActionEvent e) {
487                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
488                                         
489                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
490                                                 File file = imageChooser.getSelectedFile();
491                                                 trImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
492                                                 trImageBtn.setIcon(trImage);
493                                         }
494                                 }
495                         });
496                         
497                 }
498                 {
499                         JPanel btPanel = new JPanel();
500                         componentOverlayPanel.add(btPanel, "BODYTUBE");
501                         btPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
502                         JLabel btPartNoLabel = new JLabel("Part No:");
503                         btPanel.add(btPartNoLabel, "cell 0 0,alignx left");
504                         
505                         btPartNoTextField = new JTextField();
506                         btPanel.add(btPartNoTextField, "cell 1 0,growx");
507                         btPartNoTextField.setColumns(10);
508                         
509                         JLabel btDescLabel = new JLabel("Description:");
510                         btPanel.add(btDescLabel, "cell 3 0,alignx left");
511                         
512                         btDescTextField = new JTextField();
513                         btPanel.add(btDescTextField, "cell 4 0,growx");
514                         btDescTextField.setColumns(10);
515                         
516                         JLabel btLengthLabel = new JLabel("Length:");
517                         btPanel.add(btLengthLabel, "cell 0 1,alignx left");
518                         
519                         btLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
520                         JSpinner spin = new JSpinner(btLength.getSpinnerModel());
521                         spin.setEditor(new SpinnerEditor(spin));
522                         btPanel.add(spin, "cell 1 1, growx");
523                         btPanel.add(new UnitSelector(btLength), "growx");
524                         
525                         JLabel btMassLabel = new JLabel("Mass:");
526                         btPanel.add(btMassLabel, "cell 3 1,alignx left");
527                         
528                         btMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
529                         spin = new JSpinner(btMass.getSpinnerModel());
530                         spin.setEditor(new SpinnerEditor(spin));
531                         btPanel.add(spin, "cell 4 1, growx");
532                         btPanel.add(new UnitSelector(btMass), "w 34lp!");
533                         
534                         JLabel btInnerDiaLabel = new JLabel("Inner Dia.:");
535                         btPanel.add(btInnerDiaLabel, "cell 0 2,alignx left");
536                         
537                         btInnerDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
538                         spin = new JSpinner(btInnerDia.getSpinnerModel());
539                         spin.setEditor(new SpinnerEditor(spin));
540                         btPanel.add(spin, "cell 1 2, growx");
541                         btPanel.add(new UnitSelector(btInnerDia), "growx");
542                         
543                         JLabel btOuterDiaLabel = new JLabel("Outer Dia.:");
544                         btPanel.add(btOuterDiaLabel, "cell 3 2,alignx left");
545                         
546                         btOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
547                         spin = new JSpinner(btOuterDia.getSpinnerModel());
548                         spin.setEditor(new SpinnerEditor(spin));
549                         btPanel.add(spin, "cell 4 2, growx");
550                         btPanel.add(new UnitSelector(btOuterDia), "w 34lp!");
551                         
552                         JPanel panel = new JPanel();
553                         panel.setMinimumSize(new Dimension(200, 200));
554                         btPanel.add(panel, "cell 4 3");
555                         panel.setLayout(null);
556                         btImageBtn = new JButton("No Image");
557                         btImageBtn.setMaximumSize(new Dimension(75, 75));
558                         btImageBtn.setMinimumSize(new Dimension(75, 75));
559                         panel.add(btImageBtn);
560                         btImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
561                         
562                         btImageBtn.addActionListener(new ActionListener() {
563                                 @Override
564                                 public void actionPerformed(final ActionEvent e) {
565                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
566                                         
567                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
568                                                 File file = imageChooser.getSelectedFile();
569                                                 btImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
570                                                 btImageBtn.setIcon(btImage);
571                                         }
572                                 }
573                         });
574                         
575                 }
576                 {
577                         JPanel tcPanel = new JPanel();
578                         componentOverlayPanel.add(tcPanel, "TUBECOUPLER");
579                         tcPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
580                         JLabel tcPartNoLabel = new JLabel("Part No:");
581                         tcPanel.add(tcPartNoLabel, "cell 0 0,alignx left");
582                         
583                         tcPartNoTextField = new JTextField();
584                         tcPanel.add(tcPartNoTextField, "cell 1 0,growx");
585                         tcPartNoTextField.setColumns(10);
586                         
587                         JLabel tcDescLabel = new JLabel("Description:");
588                         tcPanel.add(tcDescLabel, "cell 3 0,alignx left");
589                         
590                         tcDescTextField = new JTextField();
591                         tcPanel.add(tcDescTextField, "cell 4 0,growx");
592                         tcDescTextField.setColumns(10);
593                         
594                         JLabel tcLengthLabel = new JLabel("Length:");
595                         tcPanel.add(tcLengthLabel, "cell 0 1,alignx left");
596                         
597                         tcLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
598                         JSpinner spin = new JSpinner(tcLength.getSpinnerModel());
599                         spin.setEditor(new SpinnerEditor(spin));
600                         tcPanel.add(spin, "cell 1 1, growx");
601                         tcPanel.add(new UnitSelector(tcLength), "growx");
602                         
603                         JLabel tcMassLabel = new JLabel("Mass:");
604                         tcPanel.add(tcMassLabel, "cell 3 1,alignx left");
605                         
606                         tcMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
607                         spin = new JSpinner(tcMass.getSpinnerModel());
608                         spin.setEditor(new SpinnerEditor(spin));
609                         tcPanel.add(spin, "cell 4 1, growx");
610                         tcPanel.add(new UnitSelector(tcMass), "w 34lp!");
611                         
612                         JLabel tcInnerDiaLabel = new JLabel("Inner Dia.:");
613                         tcPanel.add(tcInnerDiaLabel, "cell 0 2,alignx left");
614                         
615                         tcInnerDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
616                         spin = new JSpinner(tcInnerDia.getSpinnerModel());
617                         spin.setEditor(new SpinnerEditor(spin));
618                         tcPanel.add(spin, "cell 1 2, growx");
619                         tcPanel.add(new UnitSelector(tcInnerDia), "growx");
620                         
621                         JLabel tcOuterDiaLabel = new JLabel("Outer Dia.:");
622                         tcPanel.add(tcOuterDiaLabel, "cell 3 2,alignx left");
623                         
624                         tcOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
625                         spin = new JSpinner(tcOuterDia.getSpinnerModel());
626                         spin.setEditor(new SpinnerEditor(spin));
627                         tcPanel.add(spin, "cell 4 2, growx");
628                         tcPanel.add(new UnitSelector(tcOuterDia), "w 34lp!");
629                         
630                         JPanel panel = new JPanel();
631                         panel.setMinimumSize(new Dimension(200, 200));
632                         tcPanel.add(panel, "cell 4 3");
633                         panel.setLayout(null);
634                         tcImageBtn = new JButton("No Image");
635                         tcImageBtn.setMaximumSize(new Dimension(75, 75));
636                         tcImageBtn.setMinimumSize(new Dimension(75, 75));
637                         panel.add(tcImageBtn);
638                         tcImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
639                         
640                         tcImageBtn.addActionListener(new ActionListener() {
641                                 @Override
642                                 public void actionPerformed(final ActionEvent e) {
643                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
644                                         
645                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
646                                                 File file = imageChooser.getSelectedFile();
647                                                 tcImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
648                                                 tcImageBtn.setIcon(tcImage);
649                                         }
650                                 }
651                         });
652                         
653                         
654                 }
655                 {
656                         JPanel bhPanel = new JPanel();
657                         componentOverlayPanel.add(bhPanel, "BULKHEAD");
658                         bhPanel.setLayout(new MigLayout("", "[][157.00,grow 79][65.00][grow]", "[][][][]"));
659                         
660                         JLabel bhPartNoLabel = new JLabel("Part No:");
661                         bhPanel.add(bhPartNoLabel, "cell 0 0,alignx left");
662                         
663                         bhPartNoTextField = new JTextField();
664                         bhPanel.add(bhPartNoTextField, "cell 1 0,growx");
665                         bhPartNoTextField.setColumns(10);
666                         
667                         JLabel bhDescLabel = new JLabel("Description:");
668                         bhPanel.add(bhDescLabel, "cell 3 0,alignx left");
669                         
670                         bhDescTextField = new JTextField();
671                         bhPanel.add(bhDescTextField, "cell 4 0,growx");
672                         bhDescTextField.setColumns(10);
673                         
674                         JLabel bhLengthLabel = new JLabel("Thickness:");
675                         bhPanel.add(bhLengthLabel, "cell 0 1,alignx left");
676                         
677                         bhLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
678                         JSpinner spin = new JSpinner(bhLength.getSpinnerModel());
679                         spin.setEditor(new SpinnerEditor(spin));
680                         bhPanel.add(spin, "cell 1 1, growx");
681                         bhPanel.add(new UnitSelector(bhLength), "w 34lp!");
682                         
683                         JLabel bhMassLabel = new JLabel("Mass:");
684                         bhPanel.add(bhMassLabel, "cell 3 1,alignx left");
685                         
686                         bhMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
687                         spin = new JSpinner(bhMass.getSpinnerModel());
688                         spin.setEditor(new SpinnerEditor(spin));
689                         bhPanel.add(spin, "cell 4 1, growx");
690                         bhPanel.add(new UnitSelector(bhMass), "growx");
691                         
692                         JLabel bhOuterDiaLabel = new JLabel("Outer Dia.:");
693                         bhPanel.add(bhOuterDiaLabel, "cell 0 2,alignx left, aligny top, pad 7 0 0 0");
694                         
695                         bhOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
696                         spin = new JSpinner(bhOuterDia.getSpinnerModel());
697                         spin.setEditor(new SpinnerEditor(spin));
698                         bhPanel.add(spin, "cell 1 2, growx, aligny top");
699                         bhPanel.add(new UnitSelector(bhOuterDia), "w 34lp!, h 27lp!, aligny top, pad 7 0 0 0");
700                         
701                         JPanel panel = new JPanel();
702                         panel.setMinimumSize(new Dimension(200, 200));
703                         bhPanel.add(panel, "cell 4 2");
704                         panel.setLayout(null);
705                         bhImageBtn = new JButton("No Image");
706                         bhImageBtn.setMaximumSize(new Dimension(75, 75));
707                         bhImageBtn.setMinimumSize(new Dimension(75, 75));
708                         panel.add(bhImageBtn);
709                         bhImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
710                         
711                         bhImageBtn.addActionListener(new ActionListener() {
712                                 @Override
713                                 public void actionPerformed(final ActionEvent e) {
714                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
715                                         
716                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
717                                                 File file = imageChooser.getSelectedFile();
718                                                 bhImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
719                                                 bhImageBtn.setIcon(bhImage);
720                                         }
721                                 }
722                         });
723                         
724                 }
725                 {
726                         JPanel crPanel = new JPanel();
727                         componentOverlayPanel.add(crPanel, "CENTERINGRING");
728                         crPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
729                         
730                         JLabel crPartNoLabel = new JLabel("Part No:");
731                         crPanel.add(crPartNoLabel, "cell 0 0,alignx left");
732                         
733                         crPartNoTextField = new JTextField();
734                         crPanel.add(crPartNoTextField, "cell 1 0, growx");
735                         crPartNoTextField.setColumns(10);
736                         
737                         JLabel crDescLabel = new JLabel("Description:");
738                         crPanel.add(crDescLabel, "cell 3 0,alignx left");
739                         
740                         crDescTextField = new JTextField();
741                         crPanel.add(crDescTextField, "cell 4 0, growx");
742                         crDescTextField.setColumns(10);
743                         
744                         JLabel crThicknessLabel = new JLabel("Thickness:");
745                         crPanel.add(crThicknessLabel, "cell 0 1,alignx left");
746                         
747                         crThickness = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
748                         JSpinner spin = new JSpinner(crThickness.getSpinnerModel());
749                         spin.setEditor(new SpinnerEditor(spin));
750                         crPanel.add(spin, "cell 1 1, growx");
751                         crPanel.add(new UnitSelector(crThickness), "growx");
752                         
753                         JLabel crMassLabel = new JLabel("Mass:");
754                         crPanel.add(crMassLabel, "cell 3 1,alignx left");
755                         
756                         crMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
757                         spin = new JSpinner(crMass.getSpinnerModel());
758                         spin.setEditor(new SpinnerEditor(spin));
759                         crPanel.add(spin, "cell 4 1, growx");
760                         crPanel.add(new UnitSelector(crMass), "w 34lp!");
761                         
762                         JLabel crOuterDiaLabel = new JLabel("Outer Dia.:");
763                         crPanel.add(crOuterDiaLabel, "cell 0 2,alignx left");
764                         
765                         crOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
766                         spin = new JSpinner(crOuterDia.getSpinnerModel());
767                         spin.setEditor(new SpinnerEditor(spin));
768                         crPanel.add(spin, "cell 1 2, growx");
769                         crPanel.add(new UnitSelector(crOuterDia), "w 34lp!");
770                         
771                         JLabel crInnerDiaLabel = new JLabel("Inner Dia.:");
772                         crPanel.add(crInnerDiaLabel, "cell 3 2,alignx left");
773                         
774                         crInnerDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
775                         spin = new JSpinner(crInnerDia.getSpinnerModel());
776                         spin.setEditor(new SpinnerEditor(spin));
777                         crPanel.add(spin, "cell 4 2, growx");
778                         crPanel.add(new UnitSelector(crInnerDia), "w 34lp!");
779                         
780                         JPanel panel = new JPanel();
781                         panel.setMinimumSize(new Dimension(200, 200));
782                         crPanel.add(panel, "cell 4 3");
783                         panel.setLayout(null);
784                         crImageBtn = new JButton("No Image");
785                         crImageBtn.setMaximumSize(new Dimension(75, 75));
786                         crImageBtn.setMinimumSize(new Dimension(75, 75));
787                         panel.add(crImageBtn);
788                         crImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
789                         
790                         crImageBtn.addActionListener(new ActionListener() {
791                                 @Override
792                                 public void actionPerformed(final ActionEvent e) {
793                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
794                                         
795                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
796                                                 File file = imageChooser.getSelectedFile();
797                                                 crImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
798                                                 crImageBtn.setIcon(crImage);
799                                         }
800                                 }
801                         });
802                         
803                 }
804                 {
805                         JPanel ebPanel = new JPanel();
806                         componentOverlayPanel.add(ebPanel, "ENGINEBLOCK");
807                         ebPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
808                         JLabel ebPartNoLabel = new JLabel("Part No:");
809                         ebPanel.add(ebPartNoLabel, "cell 0 0,alignx left");
810                         
811                         ebPartNoTextField = new JTextField();
812                         ebPanel.add(ebPartNoTextField, "cell 1 0,growx");
813                         ebPartNoTextField.setColumns(10);
814                         
815                         JLabel ebDescLabel = new JLabel("Description:");
816                         ebPanel.add(ebDescLabel, "cell 3 0,alignx left");
817                         
818                         ebDescTextField = new JTextField();
819                         ebPanel.add(ebDescTextField, "cell 4 0,growx");
820                         ebDescTextField.setColumns(10);
821                         
822                         JLabel ebThicknessLabel = new JLabel("Thickness:");
823                         ebPanel.add(ebThicknessLabel, "cell 0 1,alignx left");
824                         
825                         ebThickness = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
826                         JSpinner spin = new JSpinner(ebThickness.getSpinnerModel());
827                         spin.setEditor(new SpinnerEditor(spin));
828                         ebPanel.add(spin, "cell 1 1, growx");
829                         ebPanel.add(new UnitSelector(ebThickness), "growx");
830                         
831                         JLabel ebMassLabel = new JLabel("Mass:");
832                         ebPanel.add(ebMassLabel, "cell 3 1,alignx left");
833                         
834                         ebMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
835                         spin = new JSpinner(ebMass.getSpinnerModel());
836                         spin.setEditor(new SpinnerEditor(spin));
837                         ebPanel.add(spin, "cell 4 1, growx");
838                         ebPanel.add(new UnitSelector(ebMass), "w 34lp!");
839                         
840                         JLabel ebOuterDiaLabel = new JLabel("Outer Dia.:");
841                         ebPanel.add(ebOuterDiaLabel, "cell 0 2,alignx left");
842                         
843                         ebOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
844                         spin = new JSpinner(ebOuterDia.getSpinnerModel());
845                         spin.setEditor(new SpinnerEditor(spin));
846                         ebPanel.add(spin, "cell 1 2, growx");
847                         ebPanel.add(new UnitSelector(ebOuterDia), "growx");
848                         
849                         JLabel ebInnerDiaLabel = new JLabel("Inner Dia.:");
850                         ebPanel.add(ebInnerDiaLabel, "cell 3 2,alignx left");
851                         
852                         ebInnerDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
853                         spin = new JSpinner(ebInnerDia.getSpinnerModel());
854                         spin.setEditor(new SpinnerEditor(spin));
855                         ebPanel.add(spin, "cell 4 2, growx");
856                         ebPanel.add(new UnitSelector(ebInnerDia), "w 34lp!");
857                         
858                         JPanel panel = new JPanel();
859                         panel.setMinimumSize(new Dimension(200, 200));
860                         ebPanel.add(panel, "cell 4 3");
861                         panel.setLayout(null);
862                         ebImageBtn = new JButton("No Image");
863                         ebImageBtn.setMaximumSize(new Dimension(75, 75));
864                         ebImageBtn.setMinimumSize(new Dimension(75, 75));
865                         panel.add(ebImageBtn);
866                         ebImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
867                         
868                         ebImageBtn.addActionListener(new ActionListener() {
869                                 @Override
870                                 public void actionPerformed(final ActionEvent e) {
871                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
872                                         
873                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
874                                                 File file = imageChooser.getSelectedFile();
875                                                 ebImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
876                                                 ebImageBtn.setIcon(ebImage);
877                                         }
878                                 }
879                         });
880                 }
881                 
882                 {
883                         JPanel llPanel = new JPanel();
884                         componentOverlayPanel.add(llPanel, "LAUNCHLUG");
885                         llPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
886                         JLabel llPartNoLabel = new JLabel("Part No:");
887                         llPanel.add(llPartNoLabel, "cell 0 0,alignx left");
888                         
889                         llPartNoTextField = new JTextField();
890                         llPanel.add(llPartNoTextField, "cell 1 0,growx");
891                         llPartNoTextField.setColumns(10);
892                         
893                         JLabel llDescLabel = new JLabel("Description:");
894                         llPanel.add(llDescLabel, "cell 3 0,alignx left");
895                         
896                         llDescTextField = new JTextField();
897                         llPanel.add(llDescTextField, "cell 4 0,growx");
898                         llDescTextField.setColumns(10);
899                         
900                         JLabel llLengthLabel = new JLabel("Length:");
901                         llPanel.add(llLengthLabel, "cell 0 1,alignx left");
902                         
903                         llLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
904                         JSpinner spin = new JSpinner(llLength.getSpinnerModel());
905                         spin.setEditor(new SpinnerEditor(spin));
906                         llPanel.add(spin, "cell 1 1, growx");
907                         llPanel.add(new UnitSelector(llLength), "growx");
908                         
909                         JLabel llMassLabel = new JLabel("Mass:");
910                         llPanel.add(llMassLabel, "cell 3 1,alignx left");
911                         
912                         llMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
913                         spin = new JSpinner(llMass.getSpinnerModel());
914                         spin.setEditor(new SpinnerEditor(spin));
915                         llPanel.add(spin, "cell 4 1, growx");
916                         llPanel.add(new UnitSelector(llMass), "w 34lp!");
917                         
918                         JLabel llOuterDiaLabel = new JLabel("Outer Dia.:");
919                         llPanel.add(llOuterDiaLabel, "cell 0 2,alignx left");
920                         
921                         llOuterDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
922                         spin = new JSpinner(llOuterDia.getSpinnerModel());
923                         spin.setEditor(new SpinnerEditor(spin));
924                         llPanel.add(spin, "cell 1 2, growx");
925                         llPanel.add(new UnitSelector(llOuterDia), "growx");
926                         
927                         JLabel llInnerDiaLabel = new JLabel("Inner Dia.:");
928                         llPanel.add(llInnerDiaLabel, "cell 3 2,alignx left");
929                         
930                         llInnerDia = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
931                         spin = new JSpinner(llInnerDia.getSpinnerModel());
932                         spin.setEditor(new SpinnerEditor(spin));
933                         llPanel.add(spin, "cell 4 2, growx");
934                         llPanel.add(new UnitSelector(llInnerDia), "w 34lp!");
935                         
936                         JPanel panel = new JPanel();
937                         panel.setMinimumSize(new Dimension(200, 200));
938                         llPanel.add(panel, "cell 4 3");
939                         panel.setLayout(null);
940                         llImageBtn = new JButton("No Image");
941                         llImageBtn.setMaximumSize(new Dimension(75, 75));
942                         llImageBtn.setMinimumSize(new Dimension(75, 75));
943                         panel.add(llImageBtn);
944                         llImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
945                         
946                         llImageBtn.addActionListener(new ActionListener() {
947                                 @Override
948                                 public void actionPerformed(final ActionEvent e) {
949                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
950                                         
951                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
952                                                 File file = imageChooser.getSelectedFile();
953                                                 llImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
954                                                 llImageBtn.setIcon(llImage);
955                                         }
956                                 }
957                         });
958                 }
959                 
960                 {
961                         JPanel stPanel = new JPanel();
962                         componentOverlayPanel.add(stPanel, "STREAMER");
963                         stPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
964                         JLabel stPartNoLabel = new JLabel("Part No:");
965                         stPanel.add(stPartNoLabel, "cell 0 0,alignx left");
966                         
967                         stPartNoTextField = new JTextField();
968                         stPanel.add(stPartNoTextField, "cell 1 0,growx");
969                         stPartNoTextField.setColumns(10);
970                         
971                         JLabel stDescLabel = new JLabel("Description:");
972                         stPanel.add(stDescLabel, "cell 3 0,alignx left");
973                         
974                         stDescTextField = new JTextField();
975                         stPanel.add(stDescTextField, "cell 4 0,growx");
976                         stDescTextField.setColumns(10);
977                         
978                         JLabel stLengthLabel = new JLabel("Length:");
979                         stPanel.add(stLengthLabel, "cell 0 1,alignx left");
980                         
981                         stLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
982                         JSpinner spin = new JSpinner(stLength.getSpinnerModel());
983                         spin.setEditor(new SpinnerEditor(spin));
984                         stPanel.add(spin, "cell 1 1, growx");
985                         stPanel.add(new UnitSelector(stLength), "growx");
986                         
987                         JLabel stMassLabel = new JLabel("Mass:");
988                         stPanel.add(stMassLabel, "cell 3 1,alignx left");
989                         
990                         stMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
991                         spin = new JSpinner(stMass.getSpinnerModel());
992                         spin.setEditor(new SpinnerEditor(spin));
993                         stPanel.add(spin, "cell 4 1, growx");
994                         stPanel.add(new UnitSelector(stMass), "growx");
995                         
996                         JLabel stThicknessLabel = new JLabel("Thickness:");
997                         stPanel.add(stThicknessLabel, "cell 0 2,alignx left");
998                         
999                         stThickness = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
1000                         spin = new JSpinner(stThickness.getSpinnerModel());
1001                         spin.setEditor(new SpinnerEditor(spin));
1002                         stPanel.add(spin, "cell 1 2, growx");
1003                         stPanel.add(new UnitSelector(stThickness), "growx");
1004                         
1005                         JLabel stWidthLabel = new JLabel("Width:");
1006                         stPanel.add(stWidthLabel, "cell 3 2,alignx left");
1007                         
1008                         stWidth = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
1009                         spin = new JSpinner(stWidth.getSpinnerModel());
1010                         spin.setEditor(new SpinnerEditor(spin));
1011                         stPanel.add(spin, "cell 4 2, growx");
1012                         stPanel.add(new UnitSelector(stWidth), "growx");
1013                         
1014                         JPanel panel = new JPanel();
1015                         panel.setMinimumSize(new Dimension(200, 200));
1016                         stPanel.add(panel, "cell 4 3");
1017                         panel.setLayout(null);
1018                         stImageBtn = new JButton("No Image");
1019                         stImageBtn.setMaximumSize(new Dimension(75, 75));
1020                         stImageBtn.setMinimumSize(new Dimension(75, 75));
1021                         panel.add(stImageBtn);
1022                         stImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
1023                         
1024                         stImageBtn.addActionListener(new ActionListener() {
1025                                 @Override
1026                                 public void actionPerformed(final ActionEvent e) {
1027                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
1028                                         
1029                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
1030                                                 File file = imageChooser.getSelectedFile();
1031                                                 stImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
1032                                                 stImageBtn.setIcon(stImage);
1033                                         }
1034                                 }
1035                         });
1036                 }
1037                 
1038                 {
1039                         JPanel pcPanel = new JPanel();
1040                         componentOverlayPanel.add(pcPanel, "PARACHUTE");
1041                         pcPanel.setLayout(new MigLayout("", "[][157.00,grow 79][65.00][grow][][]", "[][][][][][]"));
1042                         JLabel pcPartNoLabel = new JLabel("Part No:");
1043                         pcPanel.add(pcPartNoLabel, "cell 0 0,alignx left");
1044                         
1045                         pcPartNoTextField = new JTextField();
1046                         pcPanel.add(pcPartNoTextField, "cell 1 0,growx");
1047                         pcPartNoTextField.setColumns(10);
1048                         
1049                         JLabel pcDescLabel = new JLabel("Description:");
1050                         pcPanel.add(pcDescLabel, "cell 3 0,alignx left");
1051                         
1052                         pcDescTextField = new JTextField();
1053                         pcPanel.add(pcDescTextField, "cell 4 0,growx");
1054                         pcDescTextField.setColumns(10);
1055                         
1056                         JLabel pcSidesLabel = new JLabel("Sides:");
1057                         pcPanel.add(pcSidesLabel, "cell 0 1,alignx left");
1058                         
1059                         pcSides = new JTextField();
1060                         pcPanel.add(pcSides, "cell 1 1, growx");
1061                         pcSides.setInputVerifier(NON_NEGATIVE_INTEGER);
1062                         pcSides.setColumns(10);
1063                         
1064                         JLabel pcMassLabel = new JLabel("Mass:");
1065                         pcPanel.add(pcMassLabel, "cell 3 1,alignx left");
1066                         
1067                         pcMass = new DoubleModel(0, UnitGroup.UNITS_MASS, 0);
1068                         JSpinner spin = new JSpinner(pcMass.getSpinnerModel());
1069                         spin.setEditor(new SpinnerEditor(spin));
1070                         pcPanel.add(spin, "cell 4 1, growx");
1071                         pcPanel.add(new UnitSelector(pcMass), "growx");
1072                         
1073                         JLabel pcDiameterLabel = new JLabel("Diameter:");
1074                         pcPanel.add(pcDiameterLabel, "cell 0 2,alignx left");
1075                         
1076                         pcDiameter = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
1077                         spin = new JSpinner(pcDiameter.getSpinnerModel());
1078                         spin.setEditor(new SpinnerEditor(spin));
1079                         pcPanel.add(spin, "cell 1 2, growx");
1080                         pcPanel.add(new UnitSelector(pcDiameter));
1081                         
1082                         JLabel pcLineLengthLabel = new JLabel("Line Length:");
1083                         pcPanel.add(pcLineLengthLabel, "cell 3 2,alignx left");
1084                         
1085                         pcLineLength = new DoubleModel(0, UnitGroup.UNITS_LENGTH, 0);
1086                         spin = new JSpinner(pcLineLength.getSpinnerModel());
1087                         spin.setEditor(new SpinnerEditor(spin));
1088                         pcPanel.add(spin, "cell 4 2, growx");
1089                         pcPanel.add(new UnitSelector(pcLineLength), "growx");
1090                         
1091                         JLabel pcLineCountLabel = new JLabel("Line Count:");
1092                         pcPanel.add(pcLineCountLabel, "cell 3 3,alignx left");
1093                         
1094                         pcLineCount = new JTextField();
1095                         pcLineCount.setInputVerifier(NON_NEGATIVE_INTEGER);
1096                         pcPanel.add(pcLineCount, "cell 4 3, growx");
1097                         pcLineCount.setColumns(10);
1098                         
1099                         JLabel pcLineMaterialLabel = new JLabel("Line Material:");
1100                         pcPanel.add(pcLineMaterialLabel, "cell 3 4,alignx left, aligny top, pad 7 0 0 0 ");
1101                         
1102                         pcLineMaterialChooser = new MaterialChooser();
1103                         pcLineMaterialChooser.setModel(new MaterialModel(PresetEditorDialog.this, Material.Type.LINE));
1104                         pcPanel.add(pcLineMaterialChooser, "cell 4 4, span 3 1, growx, aligny top");
1105                         
1106                         JPanel panel = new JPanel();
1107                         panel.setMinimumSize(new Dimension(200, 200));
1108                         pcPanel.add(panel, "cell 1 3, span 1 3");
1109                         panel.setLayout(null);
1110                         pcImageBtn = new JButton("No Image");
1111                         pcImageBtn.setMaximumSize(new Dimension(75, 75));
1112                         pcImageBtn.setMinimumSize(new Dimension(75, 75));
1113                         panel.add(pcImageBtn);
1114                         pcImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
1115                         
1116                         pcImageBtn.addActionListener(new ActionListener() {
1117                                 @Override
1118                                 public void actionPerformed(final ActionEvent e) {
1119                                         int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
1120                                         
1121                                         if (returnVal == JFileChooser.APPROVE_OPTION) {
1122                                                 File file = imageChooser.getSelectedFile();
1123                                                 pcImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
1124                                                 pcImageBtn.setIcon(pcImage);
1125                                         }
1126                                 }
1127                         });
1128                 }
1129                 
1130                 JPanel buttonPane = new JPanel();
1131                 getContentPane().add(buttonPane, BorderLayout.SOUTH);
1132                 buttonPane.setLayout(new MigLayout("", "[130px][176.00px][131.00px]", "[29px]"));
1133                 JButton btnSaveAndNew = new JButton("Save and New");
1134                 btnSaveAndNew.addMouseListener(new MouseAdapter() {
1135                         @Override
1136                         public void mouseClicked(MouseEvent arg0) {
1137                                 saveResult();
1138                         }
1139                 });
1140                 buttonPane.add(btnSaveAndNew, "cell 0 0,alignx left,aligny top");
1141                 
1142                 JButton okButton = new JButton("Save and Close");
1143                 okButton.addActionListener(new ActionListener() {
1144                         @Override
1145                         public void actionPerformed(ActionEvent event) {
1146                                 if (saveResult()) {
1147                                         dispose();
1148                                 }
1149                         }
1150                 });
1151                 okButton.setActionCommand("OK");
1152                 buttonPane.add(okButton, "cell 1 0,alignx left,aligny top");
1153                 getRootPane().setDefaultButton(okButton);
1154                 
1155                 JButton cancelButton = new JButton("Close");
1156                 cancelButton.addActionListener(new ActionListener() {
1157                         @Override
1158                         public void actionPerformed(ActionEvent event) {
1159                                 dispose();
1160                         }
1161                 });
1162                 cancelButton.setActionCommand("Close");
1163                 buttonPane.add(cancelButton, "cell 6 0,alignx right,aligny top");
1164                 
1165                 if (toEdit != null) {
1166                         fillEditor(toEdit, matHolder);
1167                 }
1168                 holder = matHolder;
1169         }
1170         
1171         /**
1172          * When an existing preset is edited, we want to disable the other types of presets.  If the user wants a different
1173          * type of component, then they should delete this one and add a new one.
1174          *
1175          * @param cb     the combo box component
1176          * @param preset the preset being edited
1177          */
1178         private void setItems(DeselectableComboBox cb, ComponentPreset preset) {
1179                 cb.addItem(trans.get(NOSE_CONE_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.NOSE_CONE));
1180                 cb.addItem(trans.get(BODY_TUBE_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.BODY_TUBE));
1181                 cb.addItem(trans.get(BULKHEAD_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.BULK_HEAD));
1182                 cb.addItem(trans.get(CR_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.CENTERING_RING));
1183                 cb.addItem(trans.get(EB_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.ENGINE_BLOCK));
1184                 cb.addItem(trans.get(TRANSITION_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.TRANSITION));
1185                 cb.addItem(trans.get(TUBE_COUPLER_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.TUBE_COUPLER));
1186                 cb.addItem(trans.get(LAUNCH_LUG_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.LAUNCH_LUG));
1187                 cb.addItem(trans.get(PARACHUTE_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.PARACHUTE));
1188                 cb.addItem(trans.get(STREAMER_KEY), preset != null && !preset.get(ComponentPreset.TYPE).equals(ComponentPreset.Type.STREAMER));
1189         }
1190         
1191         /**
1192          * Create an image chooser.  Currently png and jpg are supported.
1193          *
1194          * @return a file chooser that looks for image files
1195          */
1196         private JFileChooser createImageChooser() {
1197                 final JFileChooser chooser = new JFileChooser();
1198                 ImagePreviewPanel preview = new ImagePreviewPanel();
1199                 chooser.setAccessory(preview);
1200                 chooser.addPropertyChangeListener(preview);
1201                 chooser.setAcceptAllFileFilterUsed(false);
1202                 chooser.addChoosableFileFilter(new FileNameExtensionFilter("Image Files", "png", "jpg", "jpeg"));
1203                 return chooser;
1204         }
1205         
1206         /**
1207          * To support editing of an existing preset, the swing components need to be prepopulated with the field data.
1208          *
1209          * @param preset the preset to edit
1210          */
1211         private void fillEditor(ComponentPreset preset, MaterialHolder holder) {
1212                 ComponentPreset.Type t = preset.getType();
1213                 
1214                 mfgTextField.setText(preset.get(ComponentPreset.MANUFACTURER).getDisplayName());
1215                 setMaterial(materialChooser, preset, holder, Material.Type.BULK, ComponentPreset.MATERIAL);
1216                 switch (t) {
1217                 case BODY_TUBE:
1218                         typeCombo.setSelectedItem(trans.get(BODY_TUBE_KEY));
1219                         btDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1220                         
1221                         if (preset.has(ComponentPreset.INNER_DIAMETER)) {
1222                                 btInnerDia.setValue(preset.get(ComponentPreset.INNER_DIAMETER));
1223                                 btInnerDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1224                         }
1225                         if (preset.has(ComponentPreset.LENGTH)) {
1226                                 btLength.setValue(preset.get(ComponentPreset.LENGTH));
1227                                 btLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1228                         }
1229                         if (preset.has(ComponentPreset.MASS)) {
1230                                 btMass.setValue(preset.get(ComponentPreset.MASS));
1231                                 btMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1232                         }
1233                         if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1234                                 btOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER));
1235                                 btOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1236                         }
1237                         if (preset.has(ComponentPreset.IMAGE)) {
1238                                 btImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1239                                 btImageBtn.setIcon(btImage);
1240                         }
1241                         btPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1242                         break;
1243                 case BULK_HEAD:
1244                         typeCombo.setSelectedItem(trans.get(BULKHEAD_KEY));
1245                         bhDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1246                         if (preset.has(ComponentPreset.LENGTH)) {
1247                                 bhLength.setValue(preset.get(ComponentPreset.LENGTH));
1248                                 bhLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1249                         }
1250                         if (preset.has(ComponentPreset.MASS)) {
1251                                 bhMass.setValue(preset.get(ComponentPreset.MASS));
1252                                 bhMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1253                         }
1254                         if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1255                                 bhOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER));
1256                                 bhOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1257                         }
1258                         if (preset.has(ComponentPreset.IMAGE)) {
1259                                 bhImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1260                                 bhImageBtn.setIcon(bhImage);
1261                         }
1262                         bhPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1263                         break;
1264                 case CENTERING_RING:
1265                         typeCombo.setSelectedItem(trans.get(CR_KEY));
1266                         crDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1267                         if (preset.has(ComponentPreset.INNER_DIAMETER)) {
1268                                 crInnerDia.setValue(preset.get(ComponentPreset.INNER_DIAMETER));
1269                                 crInnerDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1270                         }
1271                         if (preset.has(ComponentPreset.LENGTH)) {
1272                                 crThickness.setValue(preset.get(ComponentPreset.LENGTH));
1273                                 crThickness.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1274                         }
1275                         if (preset.has(ComponentPreset.MASS)) {
1276                                 crMass.setValue(preset.get(ComponentPreset.MASS));
1277                                 crMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1278                         }
1279                         if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1280                                 crOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER));
1281                                 crOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1282                         }
1283                         if (preset.has(ComponentPreset.IMAGE)) {
1284                                 crImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1285                                 crImageBtn.setIcon(crImage);
1286                         }
1287                         crPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1288                         break;
1289                 case ENGINE_BLOCK:
1290                         typeCombo.setSelectedItem(trans.get(EB_KEY));
1291                         ebDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1292                         if (preset.has(ComponentPreset.INNER_DIAMETER)) {
1293                                 ebInnerDia.setValue(preset.get(ComponentPreset.INNER_DIAMETER));
1294                                 ebInnerDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1295                         }
1296                         if (preset.has(ComponentPreset.LENGTH)) {
1297                                 ebThickness.setValue(preset.get(ComponentPreset.LENGTH));
1298                                 ebThickness.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1299                         }
1300                         if (preset.has(ComponentPreset.MASS)) {
1301                                 ebMass.setValue(preset.get(ComponentPreset.MASS));
1302                                 ebMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1303                         }
1304                         if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1305                                 ebOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER));
1306                                 ebOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1307                         }
1308                         if (preset.has(ComponentPreset.IMAGE)) {
1309                                 ebImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1310                                 ebImageBtn.setIcon(ebImage);
1311                         }
1312                         ebPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1313                         break;
1314                 case NOSE_CONE:
1315                         typeCombo.setSelectedItem(trans.get(NOSE_CONE_KEY));
1316                         ncDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1317                         if (preset.has(ComponentPreset.AFT_OUTER_DIAMETER)) {
1318                                 ncAftDia.setValue(preset.get(ComponentPreset.AFT_OUTER_DIAMETER));
1319                                 ncAftDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1320                         }
1321                         if (preset.has(ComponentPreset.AFT_SHOULDER_DIAMETER)) {
1322                                 ncAftShoulderDia.setValue(preset.get(ComponentPreset.AFT_SHOULDER_DIAMETER));
1323                                 ncAftShoulderDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1324                         }
1325                         if (preset.has(ComponentPreset.AFT_SHOULDER_LENGTH)) {
1326                                 ncAftShoulderLen.setValue(preset.get(ComponentPreset.AFT_SHOULDER_LENGTH));
1327                                 ncAftShoulderLen.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1328                         }
1329                         if (preset.has(ComponentPreset.MASS)) {
1330                                 ncMass.setValue(preset.get(ComponentPreset.MASS));
1331                                 ncMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1332                         }
1333                         if (preset.has(ComponentPreset.SHAPE)) {
1334                                 ncShapeCB.setSelectedItem(preset.get(ComponentPreset.SHAPE).toString());
1335                         }
1336                         if (preset.has(ComponentPreset.FILLED)) {
1337                                 ncFilledCB.setSelected((preset.get(ComponentPreset.FILLED)));
1338                         }
1339                         if (preset.has(ComponentPreset.LENGTH)) {
1340                                 ncLength.setValue(preset.get(ComponentPreset.LENGTH));
1341                                 ncLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1342                         }
1343                         if (preset.has(ComponentPreset.IMAGE)) {
1344                                 ncImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1345                                 ncImageBtn.setIcon(ncImage);
1346                         }
1347                         ncPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1348                         break;
1349                 case TRANSITION:
1350                         typeCombo.setSelectedItem(trans.get(TRANSITION_KEY));
1351                         trDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1352                         if (preset.has(ComponentPreset.AFT_OUTER_DIAMETER)) {
1353                                 trAftDia.setValue(preset.get(ComponentPreset.AFT_OUTER_DIAMETER));
1354                                 trAftDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1355                         }
1356                         if (preset.has(ComponentPreset.AFT_SHOULDER_DIAMETER)) {
1357                                 trAftShoulderDia.setValue(preset.get(ComponentPreset.AFT_SHOULDER_DIAMETER));
1358                                 trAftShoulderDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1359                         }
1360                         if (preset.has(ComponentPreset.AFT_SHOULDER_LENGTH)) {
1361                                 trAftShoulderLen.setValue(preset.get(ComponentPreset.AFT_SHOULDER_LENGTH));
1362                                 trAftShoulderLen.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1363                         }
1364                         if (preset.has(ComponentPreset.FORE_OUTER_DIAMETER)) {
1365                                 trForeDia.setValue(preset.get(ComponentPreset.FORE_OUTER_DIAMETER));
1366                                 trForeDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1367                         }
1368                         if (preset.has(ComponentPreset.FORE_SHOULDER_DIAMETER)) {
1369                                 trForeShoulderDia.setValue(preset.get(ComponentPreset.FORE_SHOULDER_DIAMETER));
1370                                 trForeShoulderDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1371                         }
1372                         if (preset.has(ComponentPreset.FORE_SHOULDER_LENGTH)) {
1373                                 trForeShoulderLen.setValue(preset.get(ComponentPreset.FORE_SHOULDER_LENGTH));
1374                                 trForeShoulderLen.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1375                         }
1376                         if (preset.has(ComponentPreset.MASS)) {
1377                                 trMass.setValue(preset.get(ComponentPreset.MASS));
1378                                 trMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1379                         }
1380                         if (preset.has(ComponentPreset.SHAPE)) {
1381                                 trShapeCB.setSelectedItem(preset.get(ComponentPreset.SHAPE).toString());
1382                         }
1383                         if (preset.has(ComponentPreset.FILLED)) {
1384                                 trFilledCB.setSelected((preset.get(ComponentPreset.FILLED)));
1385                         }
1386                         if (preset.has(ComponentPreset.LENGTH)) {
1387                                 trLength.setValue(preset.get(ComponentPreset.LENGTH));
1388                                 trLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1389                         }
1390                         if (preset.has(ComponentPreset.IMAGE)) {
1391                                 trImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1392                                 trImageBtn.setIcon(trImage);
1393                         }
1394                         trPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1395                         break;
1396                 case TUBE_COUPLER:
1397                         typeCombo.setSelectedItem(trans.get(TUBE_COUPLER_KEY));
1398                         tcDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1399                         if (preset.has(ComponentPreset.INNER_DIAMETER)) {
1400                                 tcInnerDia.setValue(preset.get(ComponentPreset.INNER_DIAMETER));
1401                                 tcInnerDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1402                         }
1403                         if (preset.has(ComponentPreset.LENGTH)) {
1404                                 tcLength.setValue(preset.get(ComponentPreset.LENGTH));
1405                                 tcLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1406                         }
1407                         if (preset.has(ComponentPreset.MASS)) {
1408                                 tcMass.setValue(preset.get(ComponentPreset.MASS));
1409                                 tcMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1410                         }
1411                         if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1412                                 tcOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER));
1413                                 tcOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1414                         }
1415                         tcPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1416                         if (preset.has(ComponentPreset.IMAGE)) {
1417                                 tcImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1418                                 tcImageBtn.setIcon(tcImage);
1419                         }
1420                         break;
1421                 case LAUNCH_LUG:
1422                         typeCombo.setSelectedItem(trans.get(LAUNCH_LUG_KEY));
1423                         llDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1424                         if (preset.has(ComponentPreset.INNER_DIAMETER)) {
1425                                 llInnerDia.setValue(preset.get(ComponentPreset.INNER_DIAMETER));
1426                                 llInnerDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1427                         }
1428                         if (preset.has(ComponentPreset.LENGTH)) {
1429                                 llLength.setValue(preset.get(ComponentPreset.LENGTH));
1430                                 llLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1431                         }
1432                         if (preset.has(ComponentPreset.MASS)) {
1433                                 llMass.setValue(preset.get(ComponentPreset.MASS));
1434                                 llMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1435                         }
1436                         if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1437                                 llOuterDia.setValue(preset.get(ComponentPreset.OUTER_DIAMETER));
1438                                 llOuterDia.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1439                         }
1440                         llPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1441                         if (preset.has(ComponentPreset.IMAGE)) {
1442                                 llImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1443                                 llImageBtn.setIcon(llImage);
1444                         }
1445                         break;
1446                 case PARACHUTE:
1447                         setMaterial(materialChooser, preset, holder, Material.Type.SURFACE, ComponentPreset.MATERIAL);
1448                         typeCombo.setSelectedItem(trans.get(PARACHUTE_KEY));
1449                         pcDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1450                         if (preset.has(ComponentPreset.LINE_COUNT)) {
1451                                 pcLineCount.setText(preset.get(ComponentPreset.LINE_COUNT).toString());
1452                         }
1453                         if (preset.has(ComponentPreset.SIDES)) {
1454                                 pcSides.setText(preset.get(ComponentPreset.SIDES).toString());
1455                         }
1456                         if (preset.has(ComponentPreset.MASS)) {
1457                                 pcMass.setValue(preset.get(ComponentPreset.MASS));
1458                                 pcMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1459                         }
1460                         if (preset.has(ComponentPreset.DIAMETER)) {
1461                                 pcDiameter.setValue(preset.get(ComponentPreset.DIAMETER));
1462                                 pcDiameter.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1463                         }
1464                         if (preset.has(ComponentPreset.LINE_LENGTH)) {
1465                                 pcLineLength.setValue(preset.get(ComponentPreset.LINE_LENGTH));
1466                                 pcLineLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1467                         }
1468                         pcPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1469                         if (preset.has(ComponentPreset.IMAGE)) {
1470                                 pcImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1471                                 pcImageBtn.setIcon(pcImage);
1472                         }
1473                         setMaterial(pcLineMaterialChooser, preset, holder, Material.Type.LINE, ComponentPreset.LINE_MATERIAL);
1474                         //                pcLineMaterialChooser.setModel(new MaterialModel(PresetEditorDialog.this, Material.Type.LINE));
1475                         
1476                         //                pcLineMaterialChooser.getModel().setSelectedItem(preset.get(ComponentPreset.LINE_MATERIAL));
1477                         break;
1478                 case STREAMER:
1479                         setMaterial(materialChooser, preset, holder, Material.Type.SURFACE, ComponentPreset.MATERIAL);
1480                         typeCombo.setSelectedItem(trans.get(STREAMER_KEY));
1481                         stDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1482                         if (preset.has(ComponentPreset.LENGTH)) {
1483                                 stLength.setValue(preset.get(ComponentPreset.LENGTH));
1484                                 stLength.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1485                         }
1486                         if (preset.has(ComponentPreset.THICKNESS)) {
1487                                 stThickness.setValue(preset.get(ComponentPreset.LENGTH));
1488                                 stThickness.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1489                         }
1490                         if (preset.has(ComponentPreset.MASS)) {
1491                                 stMass.setValue(preset.get(ComponentPreset.MASS));
1492                                 stMass.setCurrentUnit(UnitGroup.UNITS_MASS.getDefaultUnit());
1493                         }
1494                         if (preset.has(ComponentPreset.WIDTH)) {
1495                                 stWidth.setValue(preset.get(ComponentPreset.WIDTH));
1496                                 stWidth.setCurrentUnit(UnitGroup.UNITS_LENGTH.getDefaultUnit());
1497                         }
1498                         if (preset.has(ComponentPreset.IMAGE)) {
1499                                 stImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1500                                 stImageBtn.setIcon(stImage);
1501                         }
1502                         stPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1503                         break;
1504                 default:
1505                 }
1506         }
1507         
1508         private void setMaterial(final JComboBox chooser, final ComponentPreset preset, final MaterialHolder holder,
1509                         final Material.Type theType, final TypedKey key) {
1510                 if (holder == null) {
1511                         chooser.setModel(new MaterialModel(PresetEditorDialog.this, theType));
1512                 }
1513                 else {
1514                         chooser.setModel(new MaterialModel(PresetEditorDialog.this, theType,
1515                                         holder.asDatabase(theType)));
1516                 }
1517                 if (preset != null) {
1518                         chooser.getModel().setSelectedItem(preset.get(key));
1519                 }
1520         }
1521         
1522         /**
1523          * Extract the preset data from the UI fields, create a ComponentPreset instance, and notify the listener.
1524          */
1525         private boolean saveResult() {
1526                 String type = (String) typeCombo.getSelectedItem();
1527                 
1528                 ComponentPreset result = null;
1529                 
1530                 if (type.equals(trans.get(NOSE_CONE_KEY))) {
1531                         result = extractNoseCone();
1532                         if (result != null) {
1533                                 clearNoseCone();
1534                         }
1535                 }
1536                 else if (type.equals(trans.get(TRANSITION_KEY))) {
1537                         result = extractTransition();
1538                         if (result != null) {
1539                                 clearTransition();
1540                         }
1541                 }
1542                 else if (type.equals(trans.get(BODY_TUBE_KEY))) {
1543                         result = extractBodyTube();
1544                         if (result != null) {
1545                                 clearBodyTube();
1546                         }
1547                 }
1548                 else if (type.equals(trans.get(TUBE_COUPLER_KEY))) {
1549                         result = extractTubeCoupler();
1550                         if (result != null) {
1551                                 clearTubeCoupler();
1552                         }
1553                 }
1554                 else if (type.equals(trans.get(EB_KEY))) {
1555                         result = extractEngineBlock();
1556                         if (result != null) {
1557                                 clearEngineBlock();
1558                         }
1559                 }
1560                 else if (type.equals(trans.get(CR_KEY))) {
1561                         result = extractCenteringRing();
1562                         if (result != null) {
1563                                 clearCenteringRing();
1564                         }
1565                 }
1566                 else if (type.equals(trans.get(BULKHEAD_KEY))) {
1567                         result = extractBulkhead();
1568                         if (result != null) {
1569                                 clearBulkhead();
1570                         }
1571                 }
1572                 else if (type.equals(trans.get(LAUNCH_LUG_KEY))) {
1573                         result = extractLaunchLug();
1574                         if (result != null) {
1575                                 clearLaunchLug();
1576                         }
1577                 }
1578                 else if (type.equals(trans.get(PARACHUTE_KEY))) {
1579                         result = extractParachute();
1580                         if (result != null) {
1581                                 clearParachute();
1582                         }
1583                 }
1584                 else if (type.equals(trans.get(STREAMER_KEY))) {
1585                         result = extractStreamer();
1586                         if (result != null) {
1587                                 clearStreamer();
1588                         }
1589                 }
1590                 if (result != null) {
1591                         resultListener.notifyResult(result);
1592                         return true;
1593                 }
1594                 else {
1595                         return false;
1596                 }
1597         }
1598         
1599         private ComponentPreset extractNoseCone() {
1600                 TypedPropertyMap props = new TypedPropertyMap();
1601                 try {
1602                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.NOSE_CONE);
1603                         props.put(ComponentPreset.AFT_OUTER_DIAMETER, ncAftDia.getValue());
1604                         props.put(ComponentPreset.AFT_SHOULDER_DIAMETER, ncAftShoulderDia.getValue());
1605                         props.put(ComponentPreset.AFT_SHOULDER_LENGTH, ncAftShoulderLen.getValue());
1606                         props.put(ComponentPreset.DESCRIPTION, ncDescTextField.getText());
1607                         props.put(ComponentPreset.PARTNO, ncPartNoTextField.getText());
1608                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1609                         props.put(ComponentPreset.LENGTH, ncLength.getValue());
1610                         props.put(ComponentPreset.SHAPE, Transition.Shape.toShape((String) ncShapeCB.getSelectedItem()));
1611                         final Material material = (Material) materialChooser.getSelectedItem();
1612                         if (material != null) {
1613                                 props.put(ComponentPreset.MATERIAL, material);
1614                         }
1615                         else {
1616                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1617                                 return null;
1618                         }
1619                         props.put(ComponentPreset.MASS, ncMass.getValue());
1620                         props.put(ComponentPreset.FILLED, ncFilledCB.isSelected());
1621                         if (ncImage != null) {
1622                                 props.put(ComponentPreset.IMAGE, imageToByteArray(ncImage.getImage()));
1623                         }
1624                         
1625                         return ComponentPresetFactory.create(props);
1626                 } catch (NumberFormatException nfe) {
1627                         JOptionPane.showMessageDialog(null, "Could not convert nose cone attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1628                 } catch (InvalidComponentPresetException e) {
1629                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory nose cone attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1630                 }
1631                 return null;
1632         }
1633         
1634         private void clearNoseCone() {
1635                 ncAftDia.setValue(0);
1636                 ncAftShoulderDia.setValue(0);
1637                 ncAftShoulderLen.setValue(0);
1638                 ncDescTextField.setText("");
1639                 ncPartNoTextField.setText("");
1640                 ncLength.setValue(0);
1641                 ncMass.setValue(0);
1642                 ncFilledCB.setSelected(false);
1643                 ncImage = null;
1644                 ncImageBtn.setIcon(null);
1645         }
1646         
1647         private ComponentPreset extractTransition() {
1648                 TypedPropertyMap props = new TypedPropertyMap();
1649                 try {
1650                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.TRANSITION);
1651                         props.put(ComponentPreset.AFT_OUTER_DIAMETER, trAftDia.getValue());
1652                         props.put(ComponentPreset.AFT_SHOULDER_DIAMETER, trAftShoulderDia.getValue());
1653                         props.put(ComponentPreset.AFT_SHOULDER_LENGTH, trAftShoulderLen.getValue());
1654                         props.put(ComponentPreset.FORE_OUTER_DIAMETER, trForeDia.getValue());
1655                         props.put(ComponentPreset.FORE_SHOULDER_DIAMETER, trForeShoulderDia.getValue());
1656                         props.put(ComponentPreset.FORE_SHOULDER_LENGTH, trForeShoulderLen.getValue());
1657                         props.put(ComponentPreset.DESCRIPTION, trDescTextField.getText());
1658                         props.put(ComponentPreset.PARTNO, trPartNoTextField.getText());
1659                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1660                         
1661                         props.put(ComponentPreset.LENGTH, trLength.getValue());
1662                         props.put(ComponentPreset.SHAPE, Transition.Shape.toShape((String) trShapeCB.getSelectedItem()));
1663                         final Material material = (Material) materialChooser.getSelectedItem();
1664                         if (material != null) {
1665                                 props.put(ComponentPreset.MATERIAL, material);
1666                         }
1667                         else {
1668                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1669                                 return null;
1670                         }
1671                         props.put(ComponentPreset.MASS, trMass.getValue());
1672                         props.put(ComponentPreset.FILLED, trFilledCB.isSelected());
1673                         if (trImage != null) {
1674                                 props.put(ComponentPreset.IMAGE, imageToByteArray(trImage.getImage()));
1675                         }
1676                         
1677                         return ComponentPresetFactory.create(props);
1678                 } catch (NumberFormatException nfe) {
1679                         JOptionPane.showMessageDialog(null, "Could not convert transition attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1680                 } catch (InvalidComponentPresetException e) {
1681                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory transition attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1682                 }
1683                 return null;
1684         }
1685         
1686         private void clearTransition() {
1687                 trAftDia.setValue(0);
1688                 trAftShoulderDia.setValue(0);
1689                 trAftShoulderLen.setValue(0);
1690                 trForeDia.setValue(0);
1691                 trForeShoulderDia.setValue(0);
1692                 trForeShoulderLen.setValue(0);
1693                 trDescTextField.setText("");
1694                 trPartNoTextField.setText("");
1695                 trLength.setValue(0);
1696                 trMass.setValue(0);
1697                 trFilledCB.setSelected(false);
1698                 trImage = null;
1699                 trImageBtn.setIcon(null);
1700         }
1701         
1702         private ComponentPreset extractBodyTube() {
1703                 TypedPropertyMap props = new TypedPropertyMap();
1704                 try {
1705                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.BODY_TUBE);
1706                         props.put(ComponentPreset.OUTER_DIAMETER, btOuterDia.getValue());
1707                         props.put(ComponentPreset.INNER_DIAMETER, btInnerDia.getValue());
1708                         props.put(ComponentPreset.DESCRIPTION, btDescTextField.getText());
1709                         props.put(ComponentPreset.PARTNO, btPartNoTextField.getText());
1710                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1711                         props.put(ComponentPreset.LENGTH, btLength.getValue());
1712                         final Material material = (Material) materialChooser.getSelectedItem();
1713                         if (material != null) {
1714                                 props.put(ComponentPreset.MATERIAL, material);
1715                         }
1716                         else {
1717                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1718                                 return null;
1719                         }
1720                         props.put(ComponentPreset.MASS, btMass.getValue());
1721                         if (btImage != null) {
1722                                 props.put(ComponentPreset.IMAGE, imageToByteArray(btImage.getImage()));
1723                         }
1724                         return ComponentPresetFactory.create(props);
1725                 } catch (NumberFormatException nfe) {
1726                         JOptionPane.showMessageDialog(null, "Could not convert body tube attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1727                 } catch (InvalidComponentPresetException e) {
1728                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory body tube attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1729                 }
1730                 return null;
1731         }
1732         
1733         private void clearBodyTube() {
1734                 btOuterDia.setValue(0);
1735                 btInnerDia.setValue(0);
1736                 btDescTextField.setText("");
1737                 btPartNoTextField.setText("");
1738                 btLength.setValue(0);
1739                 btMass.setValue(0);
1740                 btImage = null;
1741                 btImageBtn.setIcon(null);
1742         }
1743         
1744         public ComponentPreset extractTubeCoupler() {
1745                 TypedPropertyMap props = new TypedPropertyMap();
1746                 try {
1747                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.TUBE_COUPLER);
1748                         props.put(ComponentPreset.OUTER_DIAMETER, tcOuterDia.getValue());
1749                         props.put(ComponentPreset.INNER_DIAMETER, tcInnerDia.getValue());
1750                         props.put(ComponentPreset.DESCRIPTION, tcDescTextField.getText());
1751                         props.put(ComponentPreset.PARTNO, tcPartNoTextField.getText());
1752                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1753                         props.put(ComponentPreset.LENGTH, tcLength.getValue());
1754                         final Material material = (Material) materialChooser.getSelectedItem();
1755                         if (material != null) {
1756                                 props.put(ComponentPreset.MATERIAL, material);
1757                         }
1758                         else {
1759                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1760                                 return null;
1761                         }
1762                         props.put(ComponentPreset.MASS, tcMass.getValue());
1763                         if (tcImage != null) {
1764                                 props.put(ComponentPreset.IMAGE, imageToByteArray(tcImage.getImage()));
1765                         }
1766                         
1767                         return ComponentPresetFactory.create(props);
1768                 } catch (NumberFormatException nfe) {
1769                         JOptionPane.showMessageDialog(null, "Could not convert tube coupler attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1770                 } catch (InvalidComponentPresetException e) {
1771                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory tube coupler attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1772                 }
1773                 return null;
1774         }
1775         
1776         private void clearTubeCoupler() {
1777                 tcOuterDia.setValue(0);
1778                 tcInnerDia.setValue(0);
1779                 tcDescTextField.setText("");
1780                 tcPartNoTextField.setText("");
1781                 tcLength.setValue(0);
1782                 tcMass.setValue(0);
1783                 tcImage = null;
1784                 tcImageBtn.setIcon(null);
1785         }
1786         
1787         private ComponentPreset extractBulkhead() {
1788                 TypedPropertyMap props = new TypedPropertyMap();
1789                 try {
1790                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.BULK_HEAD);
1791                         props.put(ComponentPreset.OUTER_DIAMETER, bhOuterDia.getValue());
1792                         props.put(ComponentPreset.DESCRIPTION, bhDescTextField.getText());
1793                         props.put(ComponentPreset.PARTNO, bhPartNoTextField.getText());
1794                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1795                         props.put(ComponentPreset.LENGTH, bhLength.getValue());
1796                         final Material material = (Material) materialChooser.getSelectedItem();
1797                         if (material != null) {
1798                                 props.put(ComponentPreset.MATERIAL, material);
1799                         }
1800                         else {
1801                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1802                                 return null;
1803                         }
1804                         props.put(ComponentPreset.MASS, bhMass.getValue());
1805                         if (bhImage != null) {
1806                                 props.put(ComponentPreset.IMAGE, imageToByteArray(bhImage.getImage()));
1807                         }
1808                         return ComponentPresetFactory.create(props);
1809                 } catch (NumberFormatException nfe) {
1810                         JOptionPane.showMessageDialog(null, "Could not convert bulkhead attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1811                 } catch (InvalidComponentPresetException e) {
1812                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory bulkhead attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1813                 }
1814                 return null;
1815         }
1816         
1817         private void clearBulkhead() {
1818                 bhOuterDia.setValue(0);
1819                 bhDescTextField.setText("");
1820                 bhPartNoTextField.setText("");
1821                 bhLength.setValue(0);
1822                 bhMass.setValue(0);
1823                 bhImage = null;
1824                 bhImageBtn.setIcon(null);
1825         }
1826         
1827         private ComponentPreset extractCenteringRing() {
1828                 TypedPropertyMap props = new TypedPropertyMap();
1829                 try {
1830                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.CENTERING_RING);
1831                         props.put(ComponentPreset.OUTER_DIAMETER, crOuterDia.getValue());
1832                         props.put(ComponentPreset.INNER_DIAMETER, crInnerDia.getValue());
1833                         props.put(ComponentPreset.DESCRIPTION, crDescTextField.getText());
1834                         props.put(ComponentPreset.PARTNO, crPartNoTextField.getText());
1835                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1836                         props.put(ComponentPreset.LENGTH, crThickness.getValue());
1837                         final Material material = (Material) materialChooser.getSelectedItem();
1838                         if (material != null) {
1839                                 props.put(ComponentPreset.MATERIAL, material);
1840                         }
1841                         else {
1842                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1843                                 return null;
1844                         }
1845                         props.put(ComponentPreset.MASS, crMass.getValue());
1846                         if (crImage != null) {
1847                                 props.put(ComponentPreset.IMAGE, imageToByteArray(crImage.getImage()));
1848                         }
1849                         return ComponentPresetFactory.create(props);
1850                 } catch (NumberFormatException nfe) {
1851                         JOptionPane.showMessageDialog(null, "Could not convert centering ring attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1852                 } catch (InvalidComponentPresetException e) {
1853                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory centering ring attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1854                 }
1855                 return null;
1856         }
1857         
1858         private void clearCenteringRing() {
1859                 crOuterDia.setValue(0);
1860                 crInnerDia.setValue(0);
1861                 crDescTextField.setText("");
1862                 crPartNoTextField.setText("");
1863                 crThickness.setValue(0);
1864                 crMass.setValue(0);
1865                 crImage = null;
1866                 crImageBtn.setIcon(null);
1867         }
1868         
1869         public ComponentPreset extractEngineBlock() {
1870                 TypedPropertyMap props = new TypedPropertyMap();
1871                 try {
1872                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.ENGINE_BLOCK);
1873                         props.put(ComponentPreset.OUTER_DIAMETER, ebOuterDia.getValue());
1874                         props.put(ComponentPreset.INNER_DIAMETER, ebInnerDia.getValue());
1875                         props.put(ComponentPreset.DESCRIPTION, ebDescTextField.getText());
1876                         props.put(ComponentPreset.PARTNO, ebPartNoTextField.getText());
1877                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1878                         props.put(ComponentPreset.LENGTH, ebThickness.getValue());
1879                         final Material material = (Material) materialChooser.getSelectedItem();
1880                         if (material != null) {
1881                                 props.put(ComponentPreset.MATERIAL, material);
1882                         }
1883                         else {
1884                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1885                                 return null;
1886                         }
1887                         props.put(ComponentPreset.MASS, ebMass.getValue());
1888                         if (ebImage != null) {
1889                                 props.put(ComponentPreset.IMAGE, imageToByteArray(ebImage.getImage()));
1890                         }
1891                         return ComponentPresetFactory.create(props);
1892                 } catch (NumberFormatException nfe) {
1893                         JOptionPane.showMessageDialog(null, "Could not convert engine block attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1894                 } catch (InvalidComponentPresetException e) {
1895                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory engine block attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1896                 }
1897                 return null;
1898         }
1899         
1900         private void clearEngineBlock() {
1901                 ebOuterDia.setValue(0);
1902                 ebInnerDia.setValue(0);
1903                 ebDescTextField.setText("");
1904                 ebPartNoTextField.setText("");
1905                 ebThickness.setValue(0);
1906                 ebMass.setValue(0);
1907                 ebImage = null;
1908                 ebImageBtn.setIcon(null);
1909         }
1910         
1911         public ComponentPreset extractLaunchLug() {
1912                 TypedPropertyMap props = new TypedPropertyMap();
1913                 try {
1914                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.LAUNCH_LUG);
1915                         props.put(ComponentPreset.OUTER_DIAMETER, llOuterDia.getValue());
1916                         props.put(ComponentPreset.INNER_DIAMETER, llInnerDia.getValue());
1917                         props.put(ComponentPreset.DESCRIPTION, llDescTextField.getText());
1918                         props.put(ComponentPreset.PARTNO, llPartNoTextField.getText());
1919                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1920                         props.put(ComponentPreset.LENGTH, llLength.getValue());
1921                         final Material material = (Material) materialChooser.getSelectedItem();
1922                         if (material != null) {
1923                                 props.put(ComponentPreset.MATERIAL, material);
1924                         }
1925                         else {
1926                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1927                                 return null;
1928                         }
1929                         props.put(ComponentPreset.MASS, llMass.getValue());
1930                         if (llImage != null) {
1931                                 props.put(ComponentPreset.IMAGE, imageToByteArray(llImage.getImage()));
1932                         }
1933                         return ComponentPresetFactory.create(props);
1934                 } catch (NumberFormatException nfe) {
1935                         JOptionPane.showMessageDialog(null, "Could not convert launch lug attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1936                 } catch (InvalidComponentPresetException e) {
1937                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory launch lug attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1938                 }
1939                 return null;
1940         }
1941         
1942         private void clearLaunchLug() {
1943                 llOuterDia.setValue(0);
1944                 llInnerDia.setValue(0);
1945                 llDescTextField.setText("");
1946                 llPartNoTextField.setText("");
1947                 llLength.setValue(0);
1948                 llMass.setValue(0);
1949                 llImage = null;
1950                 llImageBtn.setIcon(null);
1951         }
1952         
1953         public ComponentPreset extractParachute() {
1954                 TypedPropertyMap props = new TypedPropertyMap();
1955                 try {
1956                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.PARACHUTE);
1957                         props.put(ComponentPreset.DIAMETER, pcDiameter.getValue());
1958                         props.put(ComponentPreset.DESCRIPTION, pcDescTextField.getText());
1959                         props.put(ComponentPreset.PARTNO, pcPartNoTextField.getText());
1960                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1961                         if (!pcLineCount.getText().equals("")) {
1962                                 props.put(ComponentPreset.LINE_COUNT, Integer.parseInt(pcLineCount.getText()));
1963                         }
1964                         if (!pcSides.getText().equals("")) {
1965                                 props.put(ComponentPreset.SIDES, Integer.parseInt(pcSides.getText()));
1966                         }
1967                         props.put(ComponentPreset.LINE_LENGTH, pcLineLength.getValue());
1968                         Material material = (Material) materialChooser.getSelectedItem();
1969                         if (material != null) {
1970                                 props.put(ComponentPreset.MATERIAL, material);
1971                         }
1972                         else {
1973                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1974                                 return null;
1975                         }
1976                         material = (Material) pcLineMaterialChooser.getSelectedItem();
1977                         if (material != null) {
1978                                 props.put(ComponentPreset.LINE_MATERIAL, material);
1979                         }
1980                         props.put(ComponentPreset.MASS, pcMass.getValue());
1981                         if (pcImage != null) {
1982                                 props.put(ComponentPreset.IMAGE, imageToByteArray(pcImage.getImage()));
1983                         }
1984                         return ComponentPresetFactory.create(props);
1985                 } catch (NumberFormatException nfe) {
1986                         JOptionPane.showMessageDialog(null, "Could not convert parachute attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1987                 } catch (InvalidComponentPresetException e) {
1988                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory parachute attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
1989                 }
1990                 return null;
1991         }
1992         
1993         private void clearParachute() {
1994                 ebOuterDia.setValue(0);
1995                 ebInnerDia.setValue(0);
1996                 ebDescTextField.setText("");
1997                 ebPartNoTextField.setText("");
1998                 ebThickness.setValue(0);
1999                 ebMass.setValue(0);
2000                 ebImage = null;
2001                 ebImageBtn.setIcon(null);
2002         }
2003         
2004         public ComponentPreset extractStreamer() {
2005                 TypedPropertyMap props = new TypedPropertyMap();
2006                 try {
2007                         props.put(ComponentPreset.TYPE, ComponentPreset.Type.STREAMER);
2008                         props.put(ComponentPreset.DESCRIPTION, stDescTextField.getText());
2009                         props.put(ComponentPreset.PARTNO, stPartNoTextField.getText());
2010                         props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
2011                         props.put(ComponentPreset.THICKNESS, stThickness.getValue());
2012                         props.put(ComponentPreset.LENGTH, stLength.getValue());
2013                         props.put(ComponentPreset.WIDTH, stWidth.getValue());
2014                         final Material material = (Material) materialChooser.getSelectedItem();
2015                         if (material != null) {
2016                                 props.put(ComponentPreset.MATERIAL, material);
2017                         }
2018                         else {
2019                                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
2020                                 return null;
2021                         }
2022                         props.put(ComponentPreset.MASS, stMass.getValue());
2023                         if (stImage != null) {
2024                                 props.put(ComponentPreset.IMAGE, imageToByteArray(stImage.getImage()));
2025                         }
2026                         return ComponentPresetFactory.create(props);
2027                 } catch (NumberFormatException nfe) {
2028                         JOptionPane.showMessageDialog(null, "Could not convert engine block attribute.", "Error", JOptionPane.ERROR_MESSAGE);
2029                 } catch (InvalidComponentPresetException e) {
2030                         JOptionPane.showMessageDialog(null, craftErrorMessage(e, "Mandatory engine block attribute not set."), "Error", JOptionPane.ERROR_MESSAGE);
2031                 }
2032                 return null;
2033         }
2034         
2035         private void clearStreamer() {
2036                 stWidth.setValue(0);
2037                 stLength.setValue(0);
2038                 stDescTextField.setText("");
2039                 stPartNoTextField.setText("");
2040                 stThickness.setValue(0);
2041                 stMass.setValue(0);
2042                 stImage = null;
2043                 stImageBtn.setIcon(null);
2044         }
2045         
2046         @Override
2047         public void itemStateChanged(ItemEvent evt) {
2048                 CardLayout cl = (CardLayout) (componentOverlayPanel.getLayout());
2049                 final String item = (String) evt.getItem();
2050                 if (materialChooser != null && evt.getStateChange() == ItemEvent.SELECTED) {
2051                         if (item.equals(trans.get(PARACHUTE_KEY)) || item.equals(trans.get(STREAMER_KEY))) {
2052                                 if (!((MaterialModel) materialChooser.getModel()).getType().equals(Material.Type.SURFACE)) {
2053                                         setMaterial(materialChooser, null, holder, Material.Type.SURFACE, ComponentPreset.MATERIAL);
2054                                 }
2055                         }
2056                         else {
2057                                 if (!((MaterialModel) materialChooser.getModel()).getType().equals(Material.Type.BULK)) {
2058                                         setMaterial(materialChooser, null, holder, Material.Type.BULK, ComponentPreset.MATERIAL);
2059                                 }
2060                         }
2061                 }
2062                 cl.show(componentOverlayPanel, componentMap.get(item));
2063         }
2064         
2065         //Todo: I18N
2066         private String craftErrorMessage(InvalidComponentPresetException e, String baseMsg) {
2067                 StringBuilder stringBuilder = new StringBuilder();
2068                 List<String> invalids = e.getErrors();
2069                 stringBuilder.append(baseMsg).append("\n");
2070                 for (int i = 0; i < invalids.size(); i++) {
2071                         String s = invalids.get(i);
2072                         stringBuilder.append(s).append("\n");
2073                 }
2074                 
2075                 return stringBuilder.toString();
2076         }
2077         
2078         /**
2079          * Convert an image to a byte array in png format.
2080          *
2081          * @param originalImage
2082          *
2083          * @return
2084          */
2085         private byte[] imageToByteArray(Image originalImage) {
2086                 byte[] imageInByte = null;
2087                 try {
2088                         BufferedImage bi = imageToBufferedImage(originalImage);
2089                         ByteArrayOutputStream baos = new ByteArrayOutputStream();
2090                         ImageIO.write(bi, "png", baos);
2091                         baos.flush();
2092                         imageInByte = baos.toByteArray();
2093                         baos.close();
2094                 } catch (IOException e) {
2095                         log.error("Could not read image.");
2096                 }
2097                 return imageInByte;
2098         }
2099         
2100         private BufferedImage imageToBufferedImage(final Image originalImage) {
2101                 BufferedImage bi = new BufferedImage(originalImage.getWidth(null), originalImage.getHeight(null), BufferedImage.TYPE_INT_RGB);
2102                 
2103                 Graphics2D g2 = bi.createGraphics();
2104                 g2.drawImage(originalImage, 0, 0, null);
2105                 return bi;
2106         }
2107         
2108         private BufferedImage byteArrayToImage(byte[] src) {
2109                 // convert byte array back to BufferedImage
2110                 InputStream in = new ByteArrayInputStream(src);
2111                 try {
2112                         return ImageIO.read(in);
2113                 } catch (IOException e) {
2114                         log.error("Could not convert image.");
2115                 }
2116                 return null;
2117         }
2118         
2119         private ImageIcon scaleImage(Image image, int targetDimension) {
2120                 int width = image.getWidth(this);
2121                 int height = image.getHeight(this);
2122                 double ratio = 1.0;
2123                 
2124                 /*
2125                  * Determine how to scale the image. Since the accessory can expand
2126                  * vertically make sure we don't go larger than 150 when scaling
2127                  * vertically.
2128                  */
2129                 if (width >= height) {
2130                         ratio = (double) (targetDimension - 5) / width;
2131                         width = targetDimension - 5;
2132                         height = (int) (height * ratio);
2133                 }
2134                 else {
2135                         if (getHeight() > 150) {
2136                                 ratio = (double) (targetDimension - 5) / height;
2137                                 height = targetDimension - 5;
2138                                 width = (int) (width * ratio);
2139                         }
2140                         else {
2141                                 ratio = (double) getHeight() / height;
2142                                 height = getHeight();
2143                                 width = (int) (width * ratio);
2144                         }
2145                 }
2146                 
2147                 return new ImageIcon(image.getScaledInstance(width, height, Image.SCALE_DEFAULT));
2148         }
2149         
2150         static class PresetInputVerifier extends InputVerifier {
2151                 
2152                 /**
2153                  * Matches user input against a regular expression.
2154                  */
2155                 private Matcher matcher;
2156                 
2157                 PresetInputVerifier(final Pattern thePattern) {
2158                         matcher = thePattern.matcher("");
2159                 }
2160                 
2161                 /**
2162                  * Return true only if the untrimmed user input matches the regular expression provided to the constructor.
2163                  *
2164                  * @param aComponent must be an instance of JTextComponent.
2165                  */
2166                 @Override
2167                 public boolean verify(JComponent aComponent) {
2168                         JTextComponent textComponent = (JTextComponent) aComponent;
2169                         String text = textComponent.getText();
2170                         matcher.reset(text);
2171                         return matcher.matches();
2172                 }
2173                 
2174                 /**
2175                  * Always returns <tt>true</tt>, in this implementation, such that focus can always transfer to another
2176                  * component whenever the validation fails.
2177                  * <p/>
2178                  * <P>If <tt>super.shouldYieldFocus</tt> returns <tt>false</tt>, then clear the text field.
2179                  *
2180                  * @param aComponent is a <tt>JTextComponent</tt>.
2181                  */
2182                 @Override
2183                 public boolean shouldYieldFocus(JComponent aComponent) {
2184                         if (!super.shouldYieldFocus(aComponent)) {
2185                                 ((JTextComponent) aComponent).setText("");
2186                         }
2187                         return true;
2188                 }
2189         }
2190         
2191         class MaterialChooser extends JComboBox {
2192                 
2193                 public MaterialChooser() {
2194                 }
2195                 
2196                 public MaterialChooser(MaterialModel model) {
2197                         super(model);
2198                 }
2199                 
2200                 /**
2201                  * Sets the data model that the <code>JComboBox</code> uses to obtain the list of items.
2202                  *
2203                  * @param aModel the <code>ComboBoxModel</code> that provides the displayed list of items
2204                  *
2205                  * @beaninfo bound: true description: Model that the combo box uses to get data to display.
2206                  */
2207                 @Override
2208                 public void setModel(final ComboBoxModel aModel) {
2209                         if (getModel() instanceof MaterialModel) {
2210                                 MaterialModel old = (MaterialModel) getModel();
2211                                 old.removeListener();
2212                         }
2213                         super.setModel(aModel);
2214                         
2215                 }
2216         }
2217 }