Initial GUI for editing and saving component presets. See ComponentPresetPanel.main...
[debian/openrocket] / core / src / net / sf / openrocket / gui / preset / PresetEditorDialog.java
1 package net.sf.openrocket.gui.preset;
2
3 import net.miginfocom.swing.MigLayout;
4 import net.sf.openrocket.gui.print.PrintUnit;
5 import net.sf.openrocket.gui.util.SwingPreferences;
6 import net.sf.openrocket.l10n.Translator;
7 import net.sf.openrocket.logging.LogHelper;
8 import net.sf.openrocket.material.Material;
9 import net.sf.openrocket.motor.Manufacturer;
10 import net.sf.openrocket.preset.ComponentPreset;
11 import net.sf.openrocket.preset.ComponentPresetFactory;
12 import net.sf.openrocket.preset.InvalidComponentPresetException;
13 import net.sf.openrocket.preset.TypedPropertyMap;
14 import net.sf.openrocket.rocketcomponent.Transition;
15 import net.sf.openrocket.startup.Application;
16
17 import javax.imageio.ImageIO;
18 import javax.swing.*;
19 import javax.swing.border.EmptyBorder;
20 import javax.swing.filechooser.FileFilter;
21 import javax.swing.text.JTextComponent;
22 import java.awt.*;
23 import java.awt.event.ActionEvent;
24 import java.awt.event.ActionListener;
25 import java.awt.event.ItemEvent;
26 import java.awt.event.ItemListener;
27 import java.awt.event.MouseAdapter;
28 import java.awt.event.MouseEvent;
29 import java.awt.image.BufferedImage;
30 import java.io.ByteArrayInputStream;
31 import java.io.ByteArrayOutputStream;
32 import java.io.File;
33 import java.io.IOException;
34 import java.io.InputStream;
35 import java.util.HashMap;
36 import java.util.Map;
37 import java.util.regex.Matcher;
38 import java.util.regex.Pattern;
39
40 public class PresetEditorDialog extends JDialog implements ItemListener {
41
42     private static Translator trans = Application.getTranslator();
43
44     private static LogHelper log = Application.getLogger();
45
46     private static final String NON_NEGATIVE_DECIMAL_FIELD = "(\\d){1,10}\\.(\\d){1,10}";
47
48     /**
49      * Input of non-negative decimals.
50      */
51     final PresetInputVerifier NON_NEGATIVE_DECIMAL =
52             new PresetInputVerifier(Pattern.compile(NON_NEGATIVE_DECIMAL_FIELD));
53
54     private final JPanel contentPanel = new JPanel();
55     private JComboBox typeCombo;
56     private JTextField mfgTextField;
57     private JComboBox materialChooser;
58     private JComboBox massUnitCombo;
59     private JComboBox lenUnitCombo;
60
61     private JTextField ncPartNoTextField;
62     private JTextField ncDescTextField;
63     private JTextField ncLengthTextField;
64     private JCheckBox ncFilledCB;
65     private JComboBox ncShapeCB;
66     private JTextField ncAftDiaTextField;
67     private JTextField ncAftShoulderDiaTextField;
68     private JTextField ncAftShoulderLenTextField;
69     private JTextField ncMassTextField;
70     private ImageIcon ncImage;
71     private JButton ncImageBtn;
72
73     private JTextField trPartNoTextField;
74     private JTextField trDescTextField;
75     private JTextField trLengthTextField;
76     private JTextField trAftDiaTextField;
77     private JTextField trAftShoulderDiaTextField;
78     private JTextField trAftShoulderLenTextField;
79     private JTextField trForeDiaTextField;
80     private JTextField trForeShoulderDiaTextField;
81     private JTextField trForeShoulderLenTextField;
82     private JTextField trMassTextField;
83     private ImageIcon trImage;
84     private JCheckBox trFilledCB;
85     private JComboBox trShapeCB;
86     private JButton trImageBtn;
87
88     private JTextField btPartNoTextField;
89     private JTextField btDescTextField;
90     private JTextField btMassTextField;
91     private JTextField btInnerDiaTextField;
92     private JTextField btOuterDiaTextField;
93     private JTextField btLengthTextField;
94     private ImageIcon btImage;
95     private JButton btImageBtn;
96
97     private JTextField tcPartNoTextField;
98     private JTextField tcDescTextField;
99     private JTextField tcMassTextField;
100     private JTextField tcInnerDiaTextField;
101     private JTextField tcOuterDiaTextField;
102     private JTextField tcLengthTextField;
103     private ImageIcon tcImage;
104     private JButton tcImageBtn;
105
106     private JTextField bhPartNoTextField;
107     private JTextField bhDescTextField;
108     private JTextField bhOuterDiaTextField;
109     private JTextField bhLengthTextField;
110     private JTextField bhMassTextField;
111     private ImageIcon bhImage;
112     private JButton bhImageBtn;
113
114     private JTextField crPartNoTextField;
115     private JTextField crDescTextField;
116     private JTextField crOuterDiaTextField;
117     private JTextField crInnerDiaTextField;
118     private JTextField crThicknessTextField;
119     private JTextField crMassTextField;
120     private ImageIcon crImage;
121     private JButton crImageBtn;
122
123     private JTextField ebPartNoTextField;
124     private JTextField ebDescTextField;
125     private JTextField ebOuterDiaTextField;
126     private JTextField ebInnerDiaTextField;
127     private JTextField ebThicknessTextField;
128     private JTextField ebMassTextField;
129     private ImageIcon ebImage;
130     private JButton ebImageBtn;
131
132     private final JFileChooser imageChooser = createImageChooser();
133
134     private JPanel componentOverlayPanel;
135
136     private PresetResultListener resultListener;
137
138     private static Map<String, String> componentMap = new HashMap<String, String>();
139     private static Map<String, PrintUnit> lengthMap = new HashMap<String, PrintUnit>();
140
141     private static final String NOSE_CONE_KEY = "NoseCone.NoseCone";
142     private static final String BODY_TUBE_KEY = "BodyTube.BodyTube";
143     private static final String TUBE_COUPLER_KEY = "TubeCoupler.TubeCoupler";
144     private static final String TRANSITION_KEY = "Transition.Transition";
145     private static final String CR_KEY = "ComponentIcons.Centeringring";
146     private static final String BULKHEAD_KEY = "Bulkhead.Bulkhead";
147     private static final String EB_KEY = "ComponentIcons.Engineblock";
148
149
150     static {
151         componentMap.put(trans.get(NOSE_CONE_KEY), "NOSECONE");
152         componentMap.put(trans.get(BODY_TUBE_KEY), "BODYTUBE");
153         componentMap.put(trans.get(TUBE_COUPLER_KEY), "TUBECOUPLER");
154         componentMap.put(trans.get(TRANSITION_KEY), "TRANSITION");
155         componentMap.put(trans.get(CR_KEY), "CENTERINGRING");
156         componentMap.put(trans.get(BULKHEAD_KEY), "BULKHEAD");
157         componentMap.put(trans.get(EB_KEY), "ENGINEBLOCK");
158
159         lengthMap.put("m", PrintUnit.METERS);
160         lengthMap.put("cm", PrintUnit.CENTIMETERS);
161         lengthMap.put("mm", PrintUnit.MILLIMETERS);
162         lengthMap.put("in", PrintUnit.INCHES);
163         lengthMap.put("ft", PrintUnit.FOOT);
164     }
165
166     /**
167      * Launch the application.
168      */
169     public static void main(String[] args) {
170         try {
171             Application.setPreferences(new SwingPreferences());
172             PresetEditorDialog dialog = new PresetEditorDialog();
173             dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
174             dialog.setVisible(true);
175         }
176         catch (Exception e) {
177             e.printStackTrace();
178         }
179     }
180
181     /**
182      * Create the dialog.
183      */
184     public PresetEditorDialog() {
185         this(new PresetResultListener() {
186             @Override
187             public void notifyResult(final ComponentPreset preset) {
188             }
189         });
190     }
191
192     public PresetEditorDialog(PresetResultListener theCallback) {
193         this(theCallback, null);
194         typeCombo.setEditable(true);
195     }
196
197     public PresetEditorDialog(PresetResultListener theCallback, ComponentPreset toEdit) {
198         resultListener = theCallback;
199         getContentPane().setMinimumSize(new Dimension(200, 200));
200         setBounds(100, 100, 720, 610);
201         getContentPane().setLayout(new BorderLayout());
202         contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
203         getContentPane().add(contentPanel, BorderLayout.CENTER);
204         contentPanel.setLayout(new MigLayout("", "[][grow][94.00,grow][232.0,grow][130.00][grow]", "[][][20.00,grow][grow]"));
205         JLabel lblManufacturer = new JLabel("Manufacturer:");
206         contentPanel.add(lblManufacturer, "cell 2 0,alignx left,aligny center");
207
208         mfgTextField = new JTextField();
209         contentPanel.add(mfgTextField, "cell 3 0,growx");
210         mfgTextField.setColumns(10);
211
212         JLabel lenUnitLabel = new JLabel("Length Unit:");
213         contentPanel.add(lenUnitLabel, "cell 4 0,alignx left,aligny center");
214
215         lenUnitCombo = new JComboBox();
216         lenUnitCombo.setModel(new DefaultComboBoxModel(new String[]{"m", "cm", "mm", "in", "ft"}));
217         contentPanel.add(lenUnitCombo, "cell 5 0,growx");
218
219         JLabel typeLabel = new JLabel("Type:");
220         contentPanel.add(typeLabel, "cell 2 1,alignx left,aligny center");
221
222         typeCombo = new JComboBox();
223         typeCombo.addItemListener(this);
224         typeCombo.setModel(new DefaultComboBoxModel(new String[]{
225                 trans.get(NOSE_CONE_KEY), trans.get(BODY_TUBE_KEY), trans.get(TUBE_COUPLER_KEY), trans.get(TRANSITION_KEY),
226                 trans.get(CR_KEY), trans.get(BULKHEAD_KEY), trans.get(EB_KEY)}));
227         contentPanel.add(typeCombo, "cell 3 1,growx");
228
229         JLabel massUnitLabel = new JLabel("Mass Unit:");
230         contentPanel.add(massUnitLabel, "cell 4 1,alignx left,aligny center");
231
232         massUnitCombo = new JComboBox();
233         massUnitCombo.setModel(new DefaultComboBoxModel(new String[]{"kg", "g", "oz", "lb"}));
234         contentPanel.add(massUnitCombo, "cell 5 1,growx");
235
236         JLabel bhMaterialLabel = new JLabel("Material:");
237         contentPanel.add(bhMaterialLabel, "cell 2 2, alignx left");
238
239         materialChooser = new JComboBox(new MaterialModel(this, Material.Type.BULK));
240         contentPanel.add(materialChooser, "cell 3 2,growx");
241
242         componentOverlayPanel = new JPanel();
243         contentPanel.add(componentOverlayPanel, "cell 1 3 5 2,grow");
244         componentOverlayPanel.setLayout(new CardLayout(0, 0));
245
246         {
247             JPanel ncPanel = new JPanel();
248             componentOverlayPanel.add(ncPanel, "NOSECONE");
249             ncPanel.setLayout(new MigLayout("", "[61px][159.00,grow][35.00][109.00,grow][189.00,grow][grow]", "[16px][][][][][]"));
250             JLabel ncPartNoLabel = new JLabel("Part No:");
251             ncPanel.add(ncPartNoLabel, "cell 0 0,alignx left,aligny center");
252
253             ncPartNoTextField = new JTextField();
254             ncPanel.add(ncPartNoTextField, "cell 1 0,growx");
255             ncPartNoTextField.setColumns(10);
256
257             JLabel ncDescLabel = new JLabel("Description:");
258             ncPanel.add(ncDescLabel, "cell 3 0,alignx left,aligny center");
259
260             ncDescTextField = new JTextField();
261             ncPanel.add(ncDescTextField, "cell 4 0,growx");
262             ncDescTextField.setColumns(10);
263
264             ncFilledCB = new JCheckBox("Filled");
265             ncPanel.add(ncFilledCB, "cell 1 1");
266
267             JLabel ncMaterialLabel = new JLabel("Material:");
268             ncPanel.add(ncMaterialLabel, "cell 0 1,alignx left");
269
270             JLabel ncMassLabel = new JLabel("Mass:");
271             ncPanel.add(ncMassLabel, "cell 3 1,alignx left");
272
273             ncMassTextField = new JTextField();
274             ncMassTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
275             ncPanel.add(ncMassTextField, "cell 4 1,growx");
276             ncMassTextField.setColumns(10);
277
278             JLabel ncShapeLabel = new JLabel("Shape:");
279             ncPanel.add(ncShapeLabel, "cell 0 2,alignx left");
280
281             ncShapeCB = new JComboBox();
282             ncShapeCB.setModel(new DefaultComboBoxModel(new String[]{Transition.Shape.OGIVE.getName(),
283                     Transition.Shape.CONICAL.getName(), Transition.Shape.PARABOLIC.getName(),
284                     Transition.Shape.ELLIPSOID.getName(), Transition.Shape.HAACK.getName()}));
285             ncPanel.add(ncShapeCB, "cell 1 2,growx");
286
287             JLabel ncLengthLabel = new JLabel("Length:");
288             ncPanel.add(ncLengthLabel, "cell 3 2,alignx left");
289
290             ncLengthTextField = new JTextField();
291             ncLengthTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
292             ncPanel.add(ncLengthTextField, "cell 4 2,growx");
293             ncLengthTextField.setColumns(10);
294
295             JLabel ncAftDiaLabel = new JLabel("Aft Dia.:");
296             ncPanel.add(ncAftDiaLabel, "cell 0 3,alignx left, aligny top");
297
298             ncAftDiaTextField = new JTextField();
299             ncAftDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
300             ncPanel.add(ncAftDiaTextField, "cell 1 3,growx, aligny top");
301             ncAftDiaTextField.setColumns(10);
302
303             JLabel ncAftShoulderLenLabel = new JLabel("Aft Shoulder Len:");
304             ncPanel.add(ncAftShoulderLenLabel, "cell 0 4,alignx left, aligny top");
305
306             ncAftShoulderLenTextField = new JTextField();
307             ncAftShoulderLenTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
308             ncPanel.add(ncAftShoulderLenTextField, "cell 1 4,growx,aligny top");
309             ncAftShoulderLenTextField.setColumns(10);
310
311             JLabel ncAftShoulderDiaLabel = new JLabel("Aft Shoulder Dia.:");
312             ncPanel.add(ncAftShoulderDiaLabel, "cell 0 5,alignx left, aligny top");
313
314             ncAftShoulderDiaTextField = new JTextField();
315             ncAftShoulderDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
316             ncPanel.add(ncAftShoulderDiaTextField, "cell 1 5,growx, aligny top");
317             ncAftShoulderDiaTextField.setColumns(10);
318
319             JPanel panel = new JPanel();
320             panel.setMinimumSize(new Dimension(200, 200));
321             ncPanel.add(panel, "cell 4 3, span 1 3");
322             panel.setLayout(null);
323             ncImageBtn = new JButton("No Image");
324             ncImageBtn.setMaximumSize(new Dimension(75, 75));
325             ncImageBtn.setMinimumSize(new Dimension(75, 75));
326             panel.add(ncImageBtn);
327             ncImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
328
329             ncImageBtn.addActionListener(new ActionListener() {
330                 @Override
331                 public void actionPerformed(final ActionEvent e) {
332                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
333
334                     if (returnVal == JFileChooser.APPROVE_OPTION) {
335                         File file = imageChooser.getSelectedFile();
336                         ncImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
337                         ncImageBtn.setIcon(ncImage);
338                     }
339                 }
340             });
341
342         }
343         {
344             JPanel trPanel = new JPanel();
345             componentOverlayPanel.add(trPanel, "TRANSITION");
346             trPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][28.00][31.00][][]"));
347
348             JLabel trPartNoLabel = new JLabel("Part No:");
349             trPanel.add(trPartNoLabel, "cell 0 0,alignx left");
350
351             trPartNoTextField = new JTextField();
352             trPanel.add(trPartNoTextField, "cell 1 0,growx");
353             trPartNoTextField.setColumns(10);
354
355             JLabel trDescLabel = new JLabel("Description:");
356             trPanel.add(trDescLabel, "cell 2 0,alignx left");
357
358             trDescTextField = new JTextField();
359             trPanel.add(trDescTextField, "cell 3 0,growx");
360             trDescTextField.setColumns(10);
361
362             trFilledCB = new JCheckBox("Filled");
363             trPanel.add(trFilledCB, "cell 1 1");
364
365             JLabel trMassLabel = new JLabel("Mass:");
366             trPanel.add(trMassLabel, "cell 2 1,alignx left");
367
368             trMassTextField = new JTextField();
369             trMassTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
370             trPanel.add(trMassTextField, "cell 3 1,growx");
371             trMassTextField.setColumns(10);
372
373             JLabel trShapeLabel = new JLabel("Shape:");
374             trPanel.add(trShapeLabel, "cell 0 2,alignx left");
375
376             trShapeCB = new JComboBox();
377             trShapeCB.setModel(new DefaultComboBoxModel(new String[]{Transition.Shape.OGIVE.getName(),
378                     Transition.Shape.CONICAL.getName(), Transition.Shape.PARABOLIC.getName(),
379                     Transition.Shape.ELLIPSOID.getName(), Transition.Shape.HAACK.getName()}));
380             trPanel.add(trShapeCB, "cell 1 2,growx");
381
382             JLabel trLengthLabel = new JLabel("Length:");
383             trPanel.add(trLengthLabel, "cell 2 2,alignx left");
384
385             trLengthTextField = new JTextField();
386             trLengthTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
387             trPanel.add(trLengthTextField, "cell 3 2,growx");
388             trLengthTextField.setColumns(10);
389
390             JLabel trAftDiaLabel = new JLabel("Aft Dia.:");
391             trPanel.add(trAftDiaLabel, "cell 0 3,alignx left");
392
393             trAftDiaTextField = new JTextField();
394             trAftDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
395             trPanel.add(trAftDiaTextField, "cell 1 3,growx");
396             trAftDiaTextField.setColumns(10);
397
398             JLabel trForeDiaLabel = new JLabel("Fore Dia.:");
399             trPanel.add(trForeDiaLabel, "cell 2 3,alignx left");
400
401             trForeDiaTextField = new JTextField();
402             trForeDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
403             trPanel.add(trForeDiaTextField, "cell 3 3,growx");
404             trForeDiaTextField.setColumns(10);
405
406             JLabel trAftShouldDiaLabel = new JLabel("Aft Shoulder Dia.:");
407             trPanel.add(trAftShouldDiaLabel, "cell 0 4,alignx left");
408
409             trAftShoulderDiaTextField = new JTextField();
410             trAftShoulderDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
411             trPanel.add(trAftShoulderDiaTextField, "cell 1 4,growx");
412             trAftShoulderDiaTextField.setColumns(10);
413
414             JLabel trForeShouldDiaLabel = new JLabel("Fore Shoulder Dia.:");
415             trPanel.add(trForeShouldDiaLabel, "cell 2 4,alignx left");
416
417             trForeShoulderDiaTextField = new JTextField();
418             trForeShoulderDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
419             trPanel.add(trForeShoulderDiaTextField, "cell 3 4,growx");
420             trForeShoulderDiaTextField.setColumns(10);
421
422             JLabel trAftShoulderLenLabel = new JLabel("Aft Shoulder Len.:");
423             trPanel.add(trAftShoulderLenLabel, "cell 0 5,alignx left");
424
425             trAftShoulderLenTextField = new JTextField();
426             trAftShoulderLenTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
427             trPanel.add(trAftShoulderLenTextField, "cell 1 5,growx");
428             trAftShoulderLenTextField.setColumns(10);
429
430             JLabel lblForeShoulderLen = new JLabel("Fore Shoulder Len.:");
431             trPanel.add(lblForeShoulderLen, "cell 2 5,alignx left");
432
433             trForeShoulderLenTextField = new JTextField();
434             trForeShoulderLenTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
435             trPanel.add(trForeShoulderLenTextField, "cell 3 5,growx");
436             trForeShoulderLenTextField.setColumns(10);
437
438             JPanel panel = new JPanel();
439             panel.setMinimumSize(new Dimension(200, 200));
440             trPanel.add(panel, "cell 3 6");
441             panel.setLayout(null);
442             trImageBtn = new JButton("No Image");
443             trImageBtn.setMaximumSize(new Dimension(75, 75));
444             trImageBtn.setMinimumSize(new Dimension(75, 75));
445             panel.add(trImageBtn);
446             trImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
447
448             trImageBtn.addActionListener(new ActionListener() {
449                 @Override
450                 public void actionPerformed(final ActionEvent e) {
451                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
452
453                     if (returnVal == JFileChooser.APPROVE_OPTION) {
454                         File file = imageChooser.getSelectedFile();
455                         trImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
456                         trImageBtn.setIcon(trImage);
457                     }
458                 }
459             });
460
461         }
462         {
463             JPanel btPanel = new JPanel();
464             componentOverlayPanel.add(btPanel, "BODYTUBE");
465             btPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
466             JLabel btPartNoLabel = new JLabel("Part No:");
467             btPanel.add(btPartNoLabel, "cell 0 0,alignx left");
468
469             btPartNoTextField = new JTextField();
470             btPanel.add(btPartNoTextField, "cell 1 0,growx");
471             btPartNoTextField.setColumns(10);
472
473             JLabel btDescLabel = new JLabel("Description:");
474             btPanel.add(btDescLabel, "cell 2 0,alignx left");
475
476             btDescTextField = new JTextField();
477             btPanel.add(btDescTextField, "cell 3 0,growx");
478             btDescTextField.setColumns(10);
479
480             JLabel btMassLabel = new JLabel("Mass:");
481             btPanel.add(btMassLabel, "cell 2 1,alignx left");
482
483             btMassTextField = new JTextField();
484             btMassTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
485             btPanel.add(btMassTextField, "cell 3 1,growx");
486             btMassTextField.setColumns(10);
487
488             JLabel btInnerDiaLabel = new JLabel("Inner Dia.:");
489             btPanel.add(btInnerDiaLabel, "cell 0 2,alignx left");
490
491             btInnerDiaTextField = new JTextField();
492             btInnerDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
493             btPanel.add(btInnerDiaTextField, "cell 1 2,growx");
494             btInnerDiaTextField.setColumns(10);
495
496             JLabel btOuterDiaLabel = new JLabel("Outer Dia.:");
497             btPanel.add(btOuterDiaLabel, "cell 2 2,alignx left");
498
499             btOuterDiaTextField = new JTextField();
500             btOuterDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
501             btPanel.add(btOuterDiaTextField, "cell 3 2,growx");
502             btOuterDiaTextField.setColumns(10);
503
504             JLabel btLengthLabel = new JLabel("Length:");
505             btPanel.add(btLengthLabel, "cell 0 1,alignx left");
506
507             btLengthTextField = new JTextField();
508             btLengthTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
509             btPanel.add(btLengthTextField, "cell 1 1,growx");
510             btLengthTextField.setColumns(10);
511
512             JPanel panel = new JPanel();
513             panel.setMinimumSize(new Dimension(200, 200));
514             btPanel.add(panel, "cell 3 3");
515             panel.setLayout(null);
516             btImageBtn = new JButton("No Image");
517             btImageBtn.setMaximumSize(new Dimension(75, 75));
518             btImageBtn.setMinimumSize(new Dimension(75, 75));
519             panel.add(btImageBtn);
520             btImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
521
522             btImageBtn.addActionListener(new ActionListener() {
523                 @Override
524                 public void actionPerformed(final ActionEvent e) {
525                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
526
527                     if (returnVal == JFileChooser.APPROVE_OPTION) {
528                         File file = imageChooser.getSelectedFile();
529                         btImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
530                         btImageBtn.setIcon(btImage);
531                     }
532                 }
533             });
534
535         }
536         {
537             JPanel tcPanel = new JPanel();
538             componentOverlayPanel.add(tcPanel, "TUBECOUPLER");
539             tcPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
540             JLabel tcPartNoLabel = new JLabel("Part No:");
541             tcPanel.add(tcPartNoLabel, "cell 0 0,alignx left");
542
543             tcPartNoTextField = new JTextField();
544             tcPanel.add(tcPartNoTextField, "cell 1 0,growx");
545             tcPartNoTextField.setColumns(10);
546
547             JLabel tcDescLabel = new JLabel("Description:");
548             tcPanel.add(tcDescLabel, "cell 2 0,alignx left");
549
550             tcDescTextField = new JTextField();
551             tcPanel.add(tcDescTextField, "cell 3 0,growx");
552             tcDescTextField.setColumns(10);
553
554             JLabel tcMassLabel = new JLabel("Mass:");
555             tcPanel.add(tcMassLabel, "cell 2 1,alignx left");
556
557             tcMassTextField = new JTextField();
558             tcMassTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
559             tcPanel.add(tcMassTextField, "cell 3 1,growx");
560             tcMassTextField.setColumns(10);
561
562             JLabel tcInnerDiaLabel = new JLabel("Inner Dia.:");
563             tcPanel.add(tcInnerDiaLabel, "cell 0 2,alignx left, aligny top");
564
565             tcInnerDiaTextField = new JTextField();
566             tcInnerDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
567             tcPanel.add(tcInnerDiaTextField, "cell 1 2,growx, aligny top");
568             tcInnerDiaTextField.setColumns(10);
569
570             JLabel tcOuterDiaLabel = new JLabel("Outer Dia.:");
571             tcPanel.add(tcOuterDiaLabel, "cell 2 2,alignx left, aligny top");
572
573             tcOuterDiaTextField = new JTextField();
574             tcOuterDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
575             tcPanel.add(tcOuterDiaTextField, "cell 3 2,growx, aligny top");
576             tcOuterDiaTextField.setColumns(10);
577
578             JLabel tcLengthLabel = new JLabel("Length:");
579             tcPanel.add(tcLengthLabel, "cell 0 1,alignx left");
580
581             tcLengthTextField = new JTextField();
582             tcLengthTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
583             tcPanel.add(tcLengthTextField, "cell 1 1,growx");
584             tcLengthTextField.setColumns(10);
585
586             JPanel panel = new JPanel();
587             panel.setMinimumSize(new Dimension(200, 200));
588             tcPanel.add(panel, "cell 3 3");
589             panel.setLayout(null);
590             tcImageBtn = new JButton("No Image");
591             tcImageBtn.setMaximumSize(new Dimension(75, 75));
592             tcImageBtn.setMinimumSize(new Dimension(75, 75));
593             panel.add(tcImageBtn);
594             tcImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
595
596             tcImageBtn.addActionListener(new ActionListener() {
597                 @Override
598                 public void actionPerformed(final ActionEvent e) {
599                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
600
601                     if (returnVal == JFileChooser.APPROVE_OPTION) {
602                         File file = imageChooser.getSelectedFile();
603                         tcImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
604                         tcImageBtn.setIcon(tcImage);
605                     }
606                 }
607             });
608
609
610         }
611         {
612             JPanel bhPanel = new JPanel();
613             componentOverlayPanel.add(bhPanel, "BULKHEAD");
614             bhPanel.setLayout(new MigLayout("", "[][157.00,grow 79][65.00][grow]", "[][][][]"));
615
616             JLabel bhPartNoLabel = new JLabel("Part No:");
617             bhPanel.add(bhPartNoLabel, "cell 0 0,alignx left");
618
619             bhPartNoTextField = new JTextField();
620             bhPanel.add(bhPartNoTextField, "cell 1 0,growx");
621             bhPartNoTextField.setColumns(10);
622
623             JLabel bhDescLabel = new JLabel("Description:");
624             bhPanel.add(bhDescLabel, "cell 2 0,alignx left");
625
626             bhDescTextField = new JTextField();
627             bhPanel.add(bhDescTextField, "cell 3 0,growx");
628             bhDescTextField.setColumns(10);
629
630             JLabel bhOuterDiaLabel = new JLabel("Outer Dia.:");
631             bhPanel.add(bhOuterDiaLabel, "cell 0 2,alignx left, aligny top");
632
633             bhOuterDiaTextField = new JTextField();
634             bhPanel.add(bhOuterDiaTextField, "cell 1 2,growx, aligny top");
635             bhOuterDiaTextField.setColumns(10);
636
637             JLabel bhMassLabel = new JLabel("Mass:");
638             bhPanel.add(bhMassLabel, "cell 2 1,alignx left");
639
640             bhMassTextField = new JTextField();
641             bhPanel.add(bhMassTextField, "cell 3 1,growx");
642             bhMassTextField.setColumns(10);
643
644             JLabel bhLengthLabel = new JLabel("Thickness:");
645             bhPanel.add(bhLengthLabel, "cell 0 1,alignx left");
646
647             bhLengthTextField = new JTextField();
648             bhPanel.add(bhLengthTextField, "cell 1 1,growx");
649             bhLengthTextField.setColumns(10);
650
651             JPanel panel = new JPanel();
652             panel.setMinimumSize(new Dimension(200, 200));
653             bhPanel.add(panel, "cell 3 2");
654             panel.setLayout(null);
655             bhImageBtn = new JButton("No Image");
656             bhImageBtn.setMaximumSize(new Dimension(75, 75));
657             bhImageBtn.setMinimumSize(new Dimension(75, 75));
658             panel.add(bhImageBtn);
659             bhImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
660
661             bhImageBtn.addActionListener(new ActionListener() {
662                 @Override
663                 public void actionPerformed(final ActionEvent e) {
664                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
665
666                     if (returnVal == JFileChooser.APPROVE_OPTION) {
667                         File file = imageChooser.getSelectedFile();
668                         bhImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
669                         bhImageBtn.setIcon(bhImage);
670                     }
671                 }
672             });
673
674         }
675         {
676             JPanel crPanel = new JPanel();
677             componentOverlayPanel.add(crPanel, "CENTERINGRING");
678             crPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
679
680             JLabel crPartNoLabel = new JLabel("Part No:");
681             crPanel.add(crPartNoLabel, "cell 0 0,alignx left");
682
683             crPartNoTextField = new JTextField();
684             crPanel.add(crPartNoTextField, "cell 1 0, growx");
685             crPartNoTextField.setColumns(10);
686
687             JLabel crDescLabel = new JLabel("Description:");
688             crPanel.add(crDescLabel, "cell 2 0,alignx left");
689
690             crDescTextField = new JTextField();
691             crPanel.add(crDescTextField, "cell 3 0, growx");
692             crDescTextField.setColumns(10);
693
694             JLabel crMassLabel = new JLabel("Mass:");
695             crPanel.add(crMassLabel, "cell 2 1,alignx left");
696
697             crMassTextField = new JTextField();
698             crMassTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
699             crPanel.add(crMassTextField, "cell 3 1, growx");
700             crMassTextField.setColumns(10);
701
702             JLabel crOuterDiaLabel = new JLabel("Outer Dia.:");
703             crPanel.add(crOuterDiaLabel, "cell 0 2,alignx left");
704
705             crOuterDiaTextField = new JTextField();
706             crOuterDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
707             crPanel.add(crOuterDiaTextField, "cell 1 2, growx");
708             crOuterDiaTextField.setColumns(10);
709
710             JLabel crInnerDiaLabel = new JLabel("Inner Dia.:");
711             crPanel.add(crInnerDiaLabel, "cell 2 2,alignx left");
712
713             crInnerDiaTextField = new JTextField();
714             crInnerDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
715             crPanel.add(crInnerDiaTextField, "cell 3 2, growx");
716             crInnerDiaTextField.setColumns(10);
717
718             JLabel crThicknessLabel = new JLabel("Thickness:");
719             crPanel.add(crThicknessLabel, "cell 0 1,alignx left");
720
721             crThicknessTextField = new JTextField();
722             crThicknessTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
723             crPanel.add(crThicknessTextField, "cell 1 1, growx");
724             crThicknessTextField.setColumns(10);
725
726             JPanel panel = new JPanel();
727             panel.setMinimumSize(new Dimension(200, 200));
728             crPanel.add(panel, "cell 3 3");
729             panel.setLayout(null);
730             crImageBtn = new JButton("No Image");
731             crImageBtn.setMaximumSize(new Dimension(75, 75));
732             crImageBtn.setMinimumSize(new Dimension(75, 75));
733             panel.add(crImageBtn);
734             crImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
735
736             crImageBtn.addActionListener(new ActionListener() {
737                 @Override
738                 public void actionPerformed(final ActionEvent e) {
739                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
740
741                     if (returnVal == JFileChooser.APPROVE_OPTION) {
742                         File file = imageChooser.getSelectedFile();
743                         crImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
744                         crImageBtn.setIcon(crImage);
745                     }
746                 }
747             });
748
749         }
750         {
751             JPanel ebPanel = new JPanel();
752             componentOverlayPanel.add(ebPanel, "ENGINEBLOCK");
753             ebPanel.setLayout(new MigLayout("", "[][grow][][grow]", "[][][][]"));
754             JLabel ebPartNoLabel = new JLabel("Part No:");
755             ebPanel.add(ebPartNoLabel, "cell 0 0,alignx left");
756
757             ebPartNoTextField = new JTextField();
758             ebPanel.add(ebPartNoTextField, "cell 1 0,growx");
759             ebPartNoTextField.setColumns(10);
760
761             JLabel ebDescLabel = new JLabel("Description:");
762             ebPanel.add(ebDescLabel, "cell 2 0,alignx left");
763
764             ebDescTextField = new JTextField();
765             ebPanel.add(ebDescTextField, "cell 3 0,growx");
766             ebDescTextField.setColumns(10);
767
768             JLabel ebMassLabel = new JLabel("Mass:");
769             ebPanel.add(ebMassLabel, "cell 2 1,alignx left");
770
771             ebMassTextField = new JTextField();
772             ebMassTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
773             ebPanel.add(ebMassTextField, "cell 3 1,growx");
774             ebMassTextField.setColumns(10);
775
776             JLabel ebOuterDiaLabel = new JLabel("Outer Dia.:");
777             ebPanel.add(ebOuterDiaLabel, "cell 0 2,alignx left");
778
779             ebOuterDiaTextField = new JTextField();
780             ebOuterDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
781             ebPanel.add(ebOuterDiaTextField, "cell 1 2,growx");
782             ebOuterDiaTextField.setColumns(10);
783
784             JLabel ebInnerDiaLabel = new JLabel("Inner Dia.:");
785             ebPanel.add(ebInnerDiaLabel, "cell 2 2,alignx left");
786
787             ebInnerDiaTextField = new JTextField();
788             ebInnerDiaTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
789             ebPanel.add(ebInnerDiaTextField, "cell 3 2,growx");
790             ebInnerDiaTextField.setColumns(10);
791
792             JLabel ebThicknessLabel = new JLabel("Thickness:");
793             ebPanel.add(ebThicknessLabel, "cell 0 1,alignx left");
794
795             ebThicknessTextField = new JTextField();
796             ebThicknessTextField.setInputVerifier(NON_NEGATIVE_DECIMAL);
797             ebPanel.add(ebThicknessTextField, "cell 1 1,growx");
798             ebThicknessTextField.setColumns(10);
799
800             JPanel panel = new JPanel();
801             panel.setMinimumSize(new Dimension(200, 200));
802             ebPanel.add(panel, "cell 3 3");
803             panel.setLayout(null);
804             ebImageBtn = new JButton("No Image");
805             ebImageBtn.setMaximumSize(new Dimension(75, 75));
806             ebImageBtn.setMinimumSize(new Dimension(75, 75));
807             panel.add(ebImageBtn);
808             ebImageBtn.setBounds(new Rectangle(6, 6, 132, 145));
809
810             ebImageBtn.addActionListener(new ActionListener() {
811                 @Override
812                 public void actionPerformed(final ActionEvent e) {
813                     int returnVal = imageChooser.showOpenDialog(PresetEditorDialog.this);
814
815                     if (returnVal == JFileChooser.APPROVE_OPTION) {
816                         File file = imageChooser.getSelectedFile();
817                         ebImage = scaleImage(new ImageIcon(file.getAbsolutePath()).getImage(), 155);
818                         ebImageBtn.setIcon(ebImage);
819                     }
820                 }
821             });
822         }
823
824         JPanel buttonPane = new JPanel();
825         getContentPane().add(buttonPane, BorderLayout.SOUTH);
826         buttonPane.setLayout(new MigLayout("", "[130px][176.00px][131.00px]", "[29px]"));
827         JButton btnSaveAndNew = new JButton("Save and New");
828         btnSaveAndNew.addMouseListener(new MouseAdapter() {
829             @Override
830             public void mouseClicked(MouseEvent arg0) {
831                 saveResult();
832             }
833         });
834         buttonPane.add(btnSaveAndNew, "cell 0 0,alignx left,aligny top");
835
836         JButton okButton = new JButton("Save and Close");
837         okButton.addActionListener(new ActionListener() {
838             public void actionPerformed(ActionEvent event) {
839                 saveResult();
840                 dispose();
841             }
842         });
843         okButton.setActionCommand("OK");
844         buttonPane.add(okButton, "cell 1 0,alignx left,aligny top");
845         getRootPane().setDefaultButton(okButton);
846
847         JButton cancelButton = new JButton("Close");
848         cancelButton.addActionListener(new ActionListener() {
849             public void actionPerformed(ActionEvent event) {
850                 dispose();
851             }
852         });
853         cancelButton.setActionCommand("Close");
854         buttonPane.add(cancelButton, "cell 6 0,alignx right,aligny top");
855
856         if (toEdit != null) {
857             fillEditor(toEdit);
858             typeCombo.setEditable(false);
859         }
860         else {
861             typeCombo.setEditable(true);
862         }
863     }
864
865     private JFileChooser createImageChooser() {
866         final JFileChooser chooser = new JFileChooser();
867         ImagePreviewPanel preview = new ImagePreviewPanel();
868         chooser.setAccessory(preview);
869         chooser.addPropertyChangeListener(preview);
870         chooser.setAcceptAllFileFilterUsed(false);
871         chooser.addChoosableFileFilter(new FileFilter() {
872             @Override
873             public boolean accept(final File f) {
874                 return f.getName().endsWith(".png") || f.getName().endsWith(".jpg");
875             }
876
877             @Override
878             public String getDescription() {
879                 return "Image Files";
880             }
881         });
882         return chooser;
883     }
884
885     private void fillEditor(ComponentPreset preset) {
886         ComponentPreset.Type t = preset.getType();
887
888         mfgTextField.setText(preset.get(ComponentPreset.MANUFACTURER).getDisplayName());
889         materialChooser.getModel().setSelectedItem(preset.get(ComponentPreset.MATERIAL));
890         switch (t) {
891             case BODY_TUBE:
892                 typeCombo.setSelectedItem(trans.get(BODY_TUBE_KEY));
893                 btDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
894
895                 if (preset.has(ComponentPreset.INNER_DIAMETER)) {
896                     btInnerDiaTextField.setText(preset.get(ComponentPreset.INNER_DIAMETER).toString());
897                 }
898                 if (preset.has(ComponentPreset.LENGTH)) {
899                     btLengthTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
900                 }
901                 if (preset.has(ComponentPreset.MASS)) {
902                     btMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
903                 }
904                 if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
905                     btOuterDiaTextField.setText(preset.get(ComponentPreset.OUTER_DIAMETER).toString());
906                 }
907                 if (preset.has(ComponentPreset.IMAGE)) {
908                     btImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
909                     btImageBtn.setIcon(btImage);
910                 }
911                 btPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
912                 break;
913             case BULK_HEAD:
914                 typeCombo.setSelectedItem(trans.get(BULKHEAD_KEY));
915                 bhDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
916                 if (preset.has(ComponentPreset.LENGTH)) {
917                     bhLengthTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
918                 }
919                 if (preset.has(ComponentPreset.MASS)) {
920                     bhMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
921                 }
922                 if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
923                     bhOuterDiaTextField.setText(preset.get(ComponentPreset.OUTER_DIAMETER).toString());
924                 }
925                 if (preset.has(ComponentPreset.IMAGE)) {
926                     bhImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
927                     bhImageBtn.setIcon(bhImage);
928                 }
929                 bhPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
930                 break;
931             case CENTERING_RING:
932                 typeCombo.setSelectedItem(trans.get(CR_KEY));
933                 crDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
934                 if (preset.has(ComponentPreset.INNER_DIAMETER)) {
935                     crInnerDiaTextField.setText(preset.get(ComponentPreset.INNER_DIAMETER).toString());
936                 }
937                 if (preset.has(ComponentPreset.LENGTH)) {
938                     crThicknessTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
939                 }
940                 if (preset.has(ComponentPreset.MASS)) {
941                     crMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
942                 }
943                 if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
944                     crOuterDiaTextField.setText(preset.get(ComponentPreset.OUTER_DIAMETER).toString());
945                 }
946                 if (preset.has(ComponentPreset.IMAGE)) {
947                     crImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
948                     crImageBtn.setIcon(crImage);
949                 }
950                 crPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
951                 break;
952             case ENGINE_BLOCK:
953                 typeCombo.setSelectedItem(trans.get(EB_KEY));
954                 ebDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
955                 if (preset.has(ComponentPreset.INNER_DIAMETER)) {
956                     ebInnerDiaTextField.setText(preset.get(ComponentPreset.INNER_DIAMETER).toString());
957                 }
958                 if (preset.has(ComponentPreset.LENGTH)) {
959                     ebThicknessTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
960                 }
961                 if (preset.has(ComponentPreset.MASS)) {
962                     ebMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
963                 }
964                 if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
965                     ebOuterDiaTextField.setText(preset.get(ComponentPreset.OUTER_DIAMETER).toString());
966                 }
967                 if (preset.has(ComponentPreset.IMAGE)) {
968                     ebImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
969                     ebImageBtn.setIcon(ebImage);
970                 }
971                 ebPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
972                 break;
973             case NOSE_CONE:
974                 typeCombo.setSelectedItem(trans.get(NOSE_CONE_KEY));
975                 ncDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
976                 if (preset.has(ComponentPreset.AFT_OUTER_DIAMETER)) {
977                     ncAftDiaTextField.setText(preset.get(ComponentPreset.AFT_OUTER_DIAMETER).toString());
978                 }
979                 if (preset.has(ComponentPreset.AFT_SHOULDER_DIAMETER)) {
980                     ncAftShoulderDiaTextField.setText(preset.get(ComponentPreset.AFT_SHOULDER_DIAMETER).toString());
981                 }
982                 if (preset.has(ComponentPreset.AFT_SHOULDER_LENGTH)) {
983                     ncAftShoulderLenTextField.setText(preset.get(ComponentPreset.AFT_SHOULDER_LENGTH).toString());
984                 }
985                 if (preset.has(ComponentPreset.MASS)) {
986                     ncMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
987                 }
988                 if (preset.has(ComponentPreset.SHAPE)) {
989                     ncShapeCB.setSelectedItem(preset.get(ComponentPreset.SHAPE).toString());
990                 }
991                 if (preset.has(ComponentPreset.FILLED)) {
992                     ncFilledCB.setSelected((preset.get(ComponentPreset.FILLED)));
993                 }
994                 if (preset.has(ComponentPreset.LENGTH)) {
995                     ncLengthTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
996                 }
997                 if (preset.has(ComponentPreset.IMAGE)) {
998                     ncImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
999                     ncImageBtn.setIcon(ncImage);
1000                 }
1001                 ncPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1002                 break;
1003             case TRANSITION:
1004                 typeCombo.setSelectedItem(trans.get(TRANSITION_KEY));
1005                 trDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1006                 if (preset.has(ComponentPreset.AFT_OUTER_DIAMETER)) {
1007                     trAftDiaTextField.setText(preset.get(ComponentPreset.AFT_OUTER_DIAMETER).toString());
1008                 }
1009                 if (preset.has(ComponentPreset.AFT_SHOULDER_DIAMETER)) {
1010                     trAftShoulderDiaTextField.setText(preset.get(ComponentPreset.AFT_SHOULDER_DIAMETER).toString());
1011                 }
1012                 if (preset.has(ComponentPreset.AFT_SHOULDER_LENGTH)) {
1013                     trAftShoulderLenTextField.setText(preset.get(ComponentPreset.AFT_SHOULDER_LENGTH).toString());
1014                 }
1015                 if (preset.has(ComponentPreset.FORE_OUTER_DIAMETER)) {
1016                     trForeDiaTextField.setText(preset.get(ComponentPreset.FORE_OUTER_DIAMETER).toString());
1017                 }
1018                 if (preset.has(ComponentPreset.FORE_SHOULDER_DIAMETER)) {
1019                     trForeShoulderDiaTextField.setText(preset.get(ComponentPreset.FORE_SHOULDER_DIAMETER).toString());
1020                 }
1021                 if (preset.has(ComponentPreset.FORE_SHOULDER_LENGTH)) {
1022                     trForeShoulderLenTextField.setText(preset.get(ComponentPreset.FORE_SHOULDER_LENGTH).toString());
1023                 }
1024                 if (preset.has(ComponentPreset.MASS)) {
1025                     trMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
1026                 }
1027                 if (preset.has(ComponentPreset.SHAPE)) {
1028                     trShapeCB.setSelectedItem(preset.get(ComponentPreset.SHAPE).toString());
1029                 }
1030                 if (preset.has(ComponentPreset.FILLED)) {
1031                     trFilledCB.setSelected((preset.get(ComponentPreset.FILLED)));
1032                 }
1033                 if (preset.has(ComponentPreset.LENGTH)) {
1034                     trLengthTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
1035                 }
1036                 if (preset.has(ComponentPreset.IMAGE)) {
1037                     trImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1038                     trImageBtn.setIcon(trImage);
1039                 }
1040                 trPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1041                 break;
1042             case TUBE_COUPLER:
1043                 typeCombo.setSelectedItem(trans.get(TUBE_COUPLER_KEY));
1044                 tcDescTextField.setText(preset.get(ComponentPreset.DESCRIPTION));
1045                 if (preset.has(ComponentPreset.INNER_DIAMETER)) {
1046                     tcInnerDiaTextField.setText(preset.get(ComponentPreset.INNER_DIAMETER).toString());
1047                 }
1048                 if (preset.has(ComponentPreset.LENGTH)) {
1049                     tcLengthTextField.setText(preset.get(ComponentPreset.LENGTH).toString());
1050                 }
1051                 if (preset.has(ComponentPreset.MASS)) {
1052                     tcMassTextField.setText(preset.get(ComponentPreset.MASS).toString());
1053                 }
1054                 if (preset.has(ComponentPreset.OUTER_DIAMETER)) {
1055                     tcOuterDiaTextField.setText(preset.get(ComponentPreset.OUTER_DIAMETER).toString());
1056                 }
1057                 tcPartNoTextField.setText(preset.get(ComponentPreset.PARTNO));
1058                 if (preset.has(ComponentPreset.IMAGE)) {
1059                     tcImage = new ImageIcon(byteArrayToImage(preset.get(ComponentPreset.IMAGE)));
1060                     tcImageBtn.setIcon(tcImage);
1061                 }
1062                 break;
1063             default:
1064         }
1065     }
1066
1067     private void saveResult() {
1068         String type = (String) typeCombo.getSelectedItem();
1069
1070         ComponentPreset result = null;
1071
1072         if (type.equals(trans.get(NOSE_CONE_KEY))) {
1073             result = extractNoseCone();
1074             if (result != null) {
1075                 clearNoseCone();
1076             }
1077         }
1078         else if (type.equals(trans.get(TRANSITION_KEY))) {
1079             result = extractTransition();
1080             if (result != null) {
1081                 clearTransition();
1082             }
1083         }
1084         else if (type.equals(trans.get(BODY_TUBE_KEY))) {
1085             result = extractBodyTube();
1086             if (result != null) {
1087                 clearBodyTube();
1088             }
1089         }
1090         else if (type.equals(trans.get(TUBE_COUPLER_KEY))) {
1091             result = extractTubeCoupler();
1092             if (result != null) {
1093                 clearTubeCoupler();
1094             }
1095         }
1096         else if (type.equals(trans.get(EB_KEY))) {
1097             result = extractEngineBlock();
1098             if (result != null) {
1099                 clearEngineBlock();
1100             }
1101         }
1102         else if (type.equals(trans.get(CR_KEY))) {
1103             result = extractCenteringRing();
1104             if (result != null) {
1105                 clearCenteringRing();
1106             }
1107         }
1108         else if (type.equals(trans.get(BULKHEAD_KEY))) {
1109             result = extractBulkhead();
1110             if (result != null) {
1111                 clearBulkhead();
1112             }
1113         }
1114         resultListener.notifyResult(result);
1115     }
1116
1117     private ComponentPreset extractNoseCone() {
1118         TypedPropertyMap props = new TypedPropertyMap();
1119         try {
1120             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1121
1122             props.put(ComponentPreset.TYPE, ComponentPreset.Type.NOSE_CONE);
1123             if (!ncAftDiaTextField.getText().equals("")) {
1124                 props.put(ComponentPreset.AFT_OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(ncAftDiaTextField.getText())));
1125             }
1126             if (!ncAftShoulderDiaTextField.getText().equals("")) {
1127                 props.put(ComponentPreset.AFT_SHOULDER_DIAMETER, lpu.toMeters(Double.parseDouble(ncAftShoulderDiaTextField.getText())));
1128             }
1129             if (!ncAftShoulderLenTextField.getText().equals("")) {
1130                 props.put(ComponentPreset.AFT_SHOULDER_LENGTH, lpu.toMeters(Double.parseDouble(ncAftShoulderLenTextField.getText())));
1131             }
1132             props.put(ComponentPreset.DESCRIPTION, ncDescTextField.getText());
1133             props.put(ComponentPreset.PARTNO, ncPartNoTextField.getText());
1134             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1135             if (!ncLengthTextField.getText().equals("")) {
1136                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(ncLengthTextField.getText())));
1137             }
1138             props.put(ComponentPreset.SHAPE, Transition.Shape.toShape((String) ncShapeCB.getSelectedItem()));
1139             final Material material = (Material) materialChooser.getSelectedItem();
1140             if (material != null) {
1141                 props.put(ComponentPreset.MATERIAL, material);
1142             }
1143             else {
1144                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1145                 return null;
1146             }
1147             if (!ncMassTextField.getText().equals("")) {
1148                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(ncMassTextField.getText())));
1149             }
1150             props.put(ComponentPreset.FILLED, ncFilledCB.isSelected());
1151             if (ncImage != null) {
1152                 props.put(ComponentPreset.IMAGE, imageToByteArray(ncImage.getImage()));
1153             }
1154
1155             return ComponentPresetFactory.create(props);
1156         }
1157         catch (NumberFormatException nfe) {
1158             JOptionPane.showMessageDialog(null, "Could not convert nose cone attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1159         }
1160         catch (InvalidComponentPresetException e) {
1161             JOptionPane.showMessageDialog(null, "Mandatory nose cone attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1162         }
1163         return null;
1164     }
1165
1166     private void clearNoseCone() {
1167         ncAftDiaTextField.setText("");
1168         ncAftShoulderDiaTextField.setText("");
1169         ncAftShoulderLenTextField.setText("");
1170         ncDescTextField.setText("");
1171         ncPartNoTextField.setText("");
1172         ncLengthTextField.setText("");
1173         ncMassTextField.setText("");
1174         ncFilledCB.setSelected(false);
1175         ncImage = null;
1176         ncImageBtn.setIcon(null);
1177     }
1178
1179     private ComponentPreset extractTransition() {
1180         TypedPropertyMap props = new TypedPropertyMap();
1181         try {
1182             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1183             props.put(ComponentPreset.TYPE, ComponentPreset.Type.TRANSITION);
1184             if (!trAftDiaTextField.getText().equals("")) {
1185                 props.put(ComponentPreset.AFT_OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(trAftDiaTextField.getText())));
1186             }
1187             if (!trAftShoulderDiaTextField.getText().equals("")) {
1188                 props.put(ComponentPreset.AFT_SHOULDER_DIAMETER, lpu.toMeters(Double.parseDouble(trAftShoulderDiaTextField.getText())));
1189             }
1190             if (!trAftShoulderLenTextField.getText().equals("")) {
1191                 props.put(ComponentPreset.AFT_SHOULDER_LENGTH, lpu.toMeters(Double.parseDouble(trAftShoulderLenTextField.getText())));
1192             }
1193             if (!trForeDiaTextField.getText().equals("")) {
1194                 props.put(ComponentPreset.FORE_OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(trForeDiaTextField.getText())));
1195             }
1196             if (!trForeShoulderDiaTextField.getText().equals("")) {
1197                 props.put(ComponentPreset.FORE_SHOULDER_DIAMETER, lpu.toMeters(Double.parseDouble(trForeShoulderDiaTextField.getText())));
1198             }
1199             if (!trForeShoulderLenTextField.getText().equals("")) {
1200                 props.put(ComponentPreset.FORE_SHOULDER_LENGTH, lpu.toMeters(Double.parseDouble(trForeShoulderLenTextField.getText())));
1201             }
1202             props.put(ComponentPreset.DESCRIPTION, trDescTextField.getText());
1203             props.put(ComponentPreset.PARTNO, trPartNoTextField.getText());
1204             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1205
1206             if (!trLengthTextField.getText().equals("")) {
1207                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(trLengthTextField.getText())));
1208             }
1209             props.put(ComponentPreset.SHAPE, Transition.Shape.toShape((String) trShapeCB.getSelectedItem()));
1210             final Material material = (Material) materialChooser.getSelectedItem();
1211             if (material != null) {
1212                 props.put(ComponentPreset.MATERIAL, material);
1213             }
1214             else {
1215                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1216                 return null;
1217             }
1218             if (!trMassTextField.getText().equals("")) {
1219                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(trMassTextField.getText())));
1220             }
1221             props.put(ComponentPreset.FILLED, trFilledCB.isSelected());
1222             if (trImage != null) {
1223                 props.put(ComponentPreset.IMAGE, imageToByteArray(trImage.getImage()));
1224             }
1225
1226             return ComponentPresetFactory.create(props);
1227         }
1228         catch (NumberFormatException nfe) {
1229             JOptionPane.showMessageDialog(null, "Could not convert transition attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1230         }
1231         catch (InvalidComponentPresetException e) {
1232             JOptionPane.showMessageDialog(null, "Mandatory transition attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1233         }
1234         return null;
1235     }
1236
1237     private void clearTransition() {
1238         trAftDiaTextField.setText("");
1239         trAftShoulderDiaTextField.setText("");
1240         trAftShoulderLenTextField.setText("");
1241         trForeDiaTextField.setText("");
1242         trForeShoulderDiaTextField.setText("");
1243         trForeShoulderLenTextField.setText("");
1244         trDescTextField.setText("");
1245         trPartNoTextField.setText("");
1246         trLengthTextField.setText("");
1247         trMassTextField.setText("");
1248         trFilledCB.setSelected(false);
1249         trImage = null;
1250         trImageBtn.setIcon(null);
1251     }
1252
1253     private ComponentPreset extractBodyTube() {
1254         TypedPropertyMap props = new TypedPropertyMap();
1255         try {
1256             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1257             props.put(ComponentPreset.TYPE, ComponentPreset.Type.BODY_TUBE);
1258             if (!btOuterDiaTextField.getText().equals("")) {
1259                 props.put(ComponentPreset.OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(btOuterDiaTextField.getText())));
1260             }
1261             if (!btInnerDiaTextField.getText().equals("")) {
1262                 props.put(ComponentPreset.INNER_DIAMETER, lpu.toMeters(Double.parseDouble(btInnerDiaTextField.getText())));
1263             }
1264             props.put(ComponentPreset.DESCRIPTION, btDescTextField.getText());
1265             props.put(ComponentPreset.PARTNO, btPartNoTextField.getText());
1266             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1267             if (!btLengthTextField.getText().equals("")) {
1268                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(btLengthTextField.getText())));
1269             }
1270             final Material material = (Material) materialChooser.getSelectedItem();
1271             if (material != null) {
1272                 props.put(ComponentPreset.MATERIAL, material);
1273             }
1274             else {
1275                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1276                 return null;
1277             }
1278             if (!btMassTextField.getText().equals("")) {
1279                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(btMassTextField.getText())));
1280             }
1281             if (btImage != null) {
1282                 props.put(ComponentPreset.IMAGE, imageToByteArray(btImage.getImage()));
1283             }
1284             return ComponentPresetFactory.create(props);
1285         }
1286         catch (NumberFormatException nfe) {
1287             nfe.printStackTrace();
1288             JOptionPane.showMessageDialog(null, "Could not convert body tube attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1289         }
1290         catch (InvalidComponentPresetException e) {
1291             JOptionPane.showMessageDialog(null, "Mandatory body tube attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1292         }
1293         return null;
1294     }
1295
1296     private void clearBodyTube() {
1297         btOuterDiaTextField.setText("");
1298         btInnerDiaTextField.setText("");
1299         btDescTextField.setText("");
1300         btPartNoTextField.setText("");
1301         btLengthTextField.setText("");
1302         btMassTextField.setText("");
1303         btImage = null;
1304         btImageBtn.setIcon(null);
1305     }
1306
1307     public ComponentPreset extractTubeCoupler() {
1308         TypedPropertyMap props = new TypedPropertyMap();
1309         try {
1310             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1311             props.put(ComponentPreset.TYPE, ComponentPreset.Type.TUBE_COUPLER);
1312             if (!tcOuterDiaTextField.getText().equals("")) {
1313                 props.put(ComponentPreset.OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(tcOuterDiaTextField.getText())));
1314             }
1315             if (!tcInnerDiaTextField.getText().equals("")) {
1316                 props.put(ComponentPreset.INNER_DIAMETER, lpu.toMeters(Double.parseDouble(tcInnerDiaTextField.getText())));
1317             }
1318             props.put(ComponentPreset.DESCRIPTION, tcDescTextField.getText());
1319             props.put(ComponentPreset.PARTNO, tcPartNoTextField.getText());
1320             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1321             if (!tcLengthTextField.getText().equals("")) {
1322                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(tcLengthTextField.getText())));
1323             }
1324             final Material material = (Material) materialChooser.getSelectedItem();
1325             if (material != null) {
1326                 props.put(ComponentPreset.MATERIAL, material);
1327             }
1328             else {
1329                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1330                 return null;
1331             }
1332             if (!tcMassTextField.getText().equals("")) {
1333                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(tcMassTextField.getText())));
1334             }
1335             if (tcImage != null) {
1336                 props.put(ComponentPreset.IMAGE, imageToByteArray(tcImage.getImage()));
1337             }
1338
1339             return ComponentPresetFactory.create(props);
1340         }
1341         catch (NumberFormatException nfe) {
1342             JOptionPane.showMessageDialog(null, "Could not convert tube coupler attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1343         }
1344         catch (InvalidComponentPresetException e) {
1345             JOptionPane.showMessageDialog(null, "Mandatory tube coupler attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1346         }
1347         return null;
1348     }
1349
1350     private void clearTubeCoupler() {
1351         tcOuterDiaTextField.setText("");
1352         tcInnerDiaTextField.setText("");
1353         tcDescTextField.setText("");
1354         tcPartNoTextField.setText("");
1355         tcLengthTextField.setText("");
1356         tcMassTextField.setText("");
1357         tcImage = null;
1358         tcImageBtn.setIcon(null);
1359     }
1360
1361     private ComponentPreset extractBulkhead() {
1362         TypedPropertyMap props = new TypedPropertyMap();
1363         try {
1364             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1365             props.put(ComponentPreset.TYPE, ComponentPreset.Type.BULK_HEAD);
1366             if (!bhOuterDiaTextField.getText().equals("")) {
1367                 props.put(ComponentPreset.OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(bhOuterDiaTextField.getText())));
1368             }
1369             props.put(ComponentPreset.DESCRIPTION, bhDescTextField.getText());
1370             props.put(ComponentPreset.PARTNO, bhPartNoTextField.getText());
1371             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1372             if (!bhLengthTextField.getText().equals("")) {
1373                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(bhLengthTextField.getText())));
1374             }
1375             final Material material = (Material) materialChooser.getSelectedItem();
1376             if (material != null) {
1377                 props.put(ComponentPreset.MATERIAL, material);
1378             }
1379             else {
1380                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1381                 return null;
1382             }
1383             if (!bhMassTextField.getText().equals("")) {
1384                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(bhMassTextField.getText())));
1385             }
1386             if (bhImage != null) {
1387                 props.put(ComponentPreset.IMAGE, imageToByteArray(bhImage.getImage()));
1388             }
1389             return ComponentPresetFactory.create(props);
1390         }
1391         catch (NumberFormatException nfe) {
1392             JOptionPane.showMessageDialog(null, "Could not convert bulkhead attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1393         }
1394         catch (InvalidComponentPresetException e) {
1395             JOptionPane.showMessageDialog(null, "Mandatory bulkhead attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1396         }
1397         return null;
1398     }
1399
1400     private void clearBulkhead() {
1401         bhOuterDiaTextField.setText("");
1402         bhDescTextField.setText("");
1403         bhPartNoTextField.setText("");
1404         bhLengthTextField.setText("");
1405         bhMassTextField.setText("");
1406         bhImage = null;
1407         bhImageBtn.setIcon(null);
1408     }
1409
1410     private ComponentPreset extractCenteringRing() {
1411         TypedPropertyMap props = new TypedPropertyMap();
1412         try {
1413             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1414             props.put(ComponentPreset.TYPE, ComponentPreset.Type.CENTERING_RING);
1415             if (!crOuterDiaTextField.getText().equals("")) {
1416                 props.put(ComponentPreset.OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(crOuterDiaTextField.getText())));
1417             }
1418             if (!crInnerDiaTextField.getText().equals("")) {
1419                 props.put(ComponentPreset.INNER_DIAMETER, lpu.toMeters(Double.parseDouble(crInnerDiaTextField.getText())));
1420             }
1421             props.put(ComponentPreset.DESCRIPTION, crDescTextField.getText());
1422             props.put(ComponentPreset.PARTNO, crPartNoTextField.getText());
1423             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1424             if (!crThicknessTextField.getText().equals("")) {
1425                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(crThicknessTextField.getText())));
1426             }
1427             final Material material = (Material) materialChooser.getSelectedItem();
1428             if (material != null) {
1429                 props.put(ComponentPreset.MATERIAL, material);
1430             }
1431             else {
1432                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1433                 return null;
1434             }
1435             if (!crMassTextField.getText().equals("")) {
1436                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(crMassTextField.getText())));
1437             }
1438             if (crImage != null) {
1439                 props.put(ComponentPreset.IMAGE, imageToByteArray(crImage.getImage()));
1440             }
1441             return ComponentPresetFactory.create(props);
1442         }
1443         catch (NumberFormatException nfe) {
1444             JOptionPane.showMessageDialog(null, "Could not convert centering ring attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1445         }
1446         catch (InvalidComponentPresetException e) {
1447             JOptionPane.showMessageDialog(null, "Mandatory centering ring attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1448         }
1449         return null;
1450     }
1451
1452     private void clearCenteringRing() {
1453         crOuterDiaTextField.setText("");
1454         crInnerDiaTextField.setText("");
1455         crDescTextField.setText("");
1456         crPartNoTextField.setText("");
1457         crThicknessTextField.setText("");
1458         crMassTextField.setText("");
1459         crImage = null;
1460         crImageBtn.setIcon(null);
1461     }
1462
1463     public ComponentPreset extractEngineBlock() {
1464         TypedPropertyMap props = new TypedPropertyMap();
1465         try {
1466             PrintUnit lpu = lengthMap.get(lenUnitCombo.getSelectedItem());
1467             props.put(ComponentPreset.TYPE, ComponentPreset.Type.ENGINE_BLOCK);
1468             if (!ebOuterDiaTextField.getText().equals("")) {
1469                 props.put(ComponentPreset.OUTER_DIAMETER, lpu.toMeters(Double.parseDouble(ebOuterDiaTextField.getText())));
1470             }
1471             if (!ebInnerDiaTextField.getText().equals("")) {
1472                 props.put(ComponentPreset.INNER_DIAMETER, lpu.toMeters(Double.parseDouble(ebInnerDiaTextField.getText())));
1473             }
1474             props.put(ComponentPreset.DESCRIPTION, ebDescTextField.getText());
1475             props.put(ComponentPreset.PARTNO, ebPartNoTextField.getText());
1476             props.put(ComponentPreset.MANUFACTURER, Manufacturer.getManufacturer(mfgTextField.getText()));
1477             if (!ebThicknessTextField.getText().equals("")) {
1478                 props.put(ComponentPreset.LENGTH, lpu.toMeters(Double.parseDouble(ebThicknessTextField.getText())));
1479             }
1480             final Material material = (Material) materialChooser.getSelectedItem();
1481             if (material != null) {
1482                 props.put(ComponentPreset.MATERIAL, material);
1483             }
1484             else {
1485                 JOptionPane.showMessageDialog(null, "A material must be selected.", "Error", JOptionPane.ERROR_MESSAGE);
1486                 return null;
1487             }
1488             if (!ebMassTextField.getText().equals("")) {
1489                 props.put(ComponentPreset.MASS, lpu.toMeters(Double.parseDouble(ebMassTextField.getText())));
1490             }
1491             if (ebImage != null) {
1492                 props.put(ComponentPreset.IMAGE, imageToByteArray(ebImage.getImage()));
1493             }
1494             return ComponentPresetFactory.create(props);
1495         }
1496         catch (NumberFormatException nfe) {
1497             JOptionPane.showMessageDialog(null, "Could not convert engine block attribute.", "Error", JOptionPane.ERROR_MESSAGE);
1498         }
1499         catch (InvalidComponentPresetException e) {
1500             JOptionPane.showMessageDialog(null, "Mandatory engine block attribute not set.", "Error", JOptionPane.ERROR_MESSAGE);
1501         }
1502         return null;
1503     }
1504
1505     private void clearEngineBlock() {
1506         ebOuterDiaTextField.setText("");
1507         ebInnerDiaTextField.setText("");
1508         ebDescTextField.setText("");
1509         ebPartNoTextField.setText("");
1510         ebThicknessTextField.setText("");
1511         ebMassTextField.setText("");
1512         ebImage = null;
1513         ebImageBtn.setIcon(null);
1514     }
1515
1516     public void itemStateChanged(ItemEvent evt) {
1517         CardLayout cl = (CardLayout) (componentOverlayPanel.getLayout());
1518         cl.show(componentOverlayPanel, componentMap.get((String) evt.getItem()));
1519
1520     }
1521
1522     /**
1523      * Convert an image to a byte array in png format.
1524      *
1525      * @param originalImage
1526      * @return
1527      */
1528     private byte[] imageToByteArray(Image originalImage) {
1529         byte[] imageInByte = null;
1530         try {
1531             BufferedImage bi = imageToBufferedImage(originalImage);
1532             ByteArrayOutputStream baos = new ByteArrayOutputStream();
1533             ImageIO.write(bi, "png", baos);
1534             baos.flush();
1535             imageInByte = baos.toByteArray();
1536             baos.close();
1537         }
1538         catch (IOException e) {
1539             log.error("Could not read image.");
1540         }
1541         return imageInByte;
1542     }
1543
1544     private BufferedImage imageToBufferedImage(final Image originalImage) {
1545         BufferedImage bi = new BufferedImage(
1546                 originalImage.getWidth(null),
1547                 originalImage.getHeight(null),
1548                 BufferedImage.TYPE_INT_RGB);
1549
1550         Graphics2D g2 = bi.createGraphics();
1551         g2.drawImage(originalImage, 0, 0, null);
1552         return bi;
1553     }
1554
1555     private BufferedImage byteArrayToImage(byte[] src) {
1556         // convert byte array back to BufferedImage
1557         InputStream in = new ByteArrayInputStream(src);
1558         try {
1559             return ImageIO.read(in);
1560         }
1561         catch (IOException e) {
1562             log.error("Could not convert image.");
1563         }
1564         return null;
1565     }
1566
1567     private ImageIcon scaleImage(Image image, int targetDimension) {
1568         int width = image.getWidth(this);
1569         int height = image.getHeight(this);
1570         double ratio = 1.0;
1571
1572         /*
1573          * Determine how to scale the image. Since the accessory can expand
1574          * vertically make sure we don't go larger than 150 when scaling
1575          * vertically.
1576          */
1577         if (width >= height) {
1578             ratio = (double) (targetDimension - 5) / width;
1579             width = targetDimension - 5;
1580             height = (int) (height * ratio);
1581         }
1582         else {
1583             if (getHeight() > 150) {
1584                 ratio = (double) (targetDimension - 5) / height;
1585                 height = targetDimension - 5;
1586                 width = (int) (width * ratio);
1587             }
1588             else {
1589                 ratio = (double) getHeight() / height;
1590                 height = getHeight();
1591                 width = (int) (width * ratio);
1592             }
1593         }
1594
1595         return new ImageIcon(image.getScaledInstance(width, height, Image.SCALE_DEFAULT));
1596     }
1597
1598     static class PresetInputVerifier extends InputVerifier {
1599
1600         /**
1601          * Matches user input against a regular expression.
1602          */
1603         private Matcher matcher;
1604
1605         PresetInputVerifier(final Pattern thePattern) {
1606             matcher = thePattern.matcher("");
1607         }
1608
1609         /**
1610          * Return true only if the untrimmed user input matches the regular expression provided to the constructor.
1611          *
1612          * @param aComponent must be an instance of JTextComponent.
1613          */
1614         public boolean verify(JComponent aComponent) {
1615             JTextComponent textComponent = (JTextComponent) aComponent;
1616             matcher.reset(textComponent.getText());
1617             return matcher.matches();
1618         }
1619
1620         /**
1621          * Always returns <tt>true</tt>, in this implementation, such that focus can always transfer to another
1622          * component whenever the validation fails.
1623          * <p/>
1624          * <P>If <tt>super.shouldYieldFocus</tt> returns <tt>false</tt>, then clear the text field.
1625          *
1626          * @param aComponent is a <tt>JTextComponent</tt>.
1627          */
1628         @Override
1629         public boolean shouldYieldFocus(JComponent aComponent) {
1630             if (!super.shouldYieldFocus(aComponent)) {
1631                 ((JTextComponent) aComponent).setText("");
1632             }
1633             return true;
1634         }
1635     }
1636 }