create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / gui / dialogs / preferences / PreferencesDialog.java
1 package net.sf.openrocket.gui.dialogs.preferences;
2
3 import java.awt.Dialog;
4 import java.awt.Window;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.WindowAdapter;
8 import java.awt.event.WindowEvent;
9 import java.io.File;
10 import java.util.ArrayList;
11 import java.util.Collections;
12 import java.util.List;
13 import java.util.Locale;
14
15 import javax.swing.AbstractListModel;
16 import javax.swing.ComboBoxModel;
17 import javax.swing.JButton;
18 import javax.swing.JCheckBox;
19 import javax.swing.JComboBox;
20 import javax.swing.JDialog;
21 import javax.swing.JFileChooser;
22 import javax.swing.JLabel;
23 import javax.swing.JOptionPane;
24 import javax.swing.JPanel;
25 import javax.swing.JProgressBar;
26 import javax.swing.JTabbedPane;
27 import javax.swing.JTextField;
28 import javax.swing.Timer;
29 import javax.swing.event.DocumentEvent;
30 import javax.swing.event.DocumentListener;
31
32 import net.miginfocom.swing.MigLayout;
33 import net.sf.openrocket.communication.UpdateInfo;
34 import net.sf.openrocket.communication.UpdateInfoRetriever;
35 import net.sf.openrocket.gui.components.DescriptionArea;
36 import net.sf.openrocket.gui.components.StyledLabel;
37 import net.sf.openrocket.gui.components.StyledLabel.Style;
38 import net.sf.openrocket.gui.dialogs.UpdateInfoDialog;
39 import net.sf.openrocket.gui.util.GUIUtil;
40 import net.sf.openrocket.gui.util.SwingPreferences;
41 import net.sf.openrocket.gui.util.SimpleFileFilter;
42 import net.sf.openrocket.l10n.L10N;
43 import net.sf.openrocket.l10n.Translator;
44 import net.sf.openrocket.logging.LogHelper;
45 import net.sf.openrocket.startup.Application;
46 import net.sf.openrocket.startup.Preferences;
47 import net.sf.openrocket.unit.Unit;
48 import net.sf.openrocket.unit.UnitGroup;
49 import net.sf.openrocket.util.BuildProperties;
50 import net.sf.openrocket.util.Named;
51 import net.sf.openrocket.util.Utils;
52
53
54 public class PreferencesDialog extends JDialog {
55         private static final LogHelper log = Application.getLogger();
56         
57         private final List<DefaultUnitSelector> unitSelectors = new ArrayList<DefaultUnitSelector>();
58         
59         private File defaultDirectory = null;
60         private static final Translator trans = Application.getTranslator();
61         
62         private PreferencesDialog(Window parent) {
63                 //// Preferences
64                 super(parent, trans.get("pref.dlg.title.Preferences"), Dialog.ModalityType.APPLICATION_MODAL);
65                 
66                 JPanel panel = new JPanel(new MigLayout("fill, gap unrel", "[grow]", "[grow][]"));
67                 
68                 JTabbedPane tabbedPane = new JTabbedPane();
69                 panel.add(tabbedPane, "grow, wrap");
70                 
71                 //// Units and Default units
72                 tabbedPane.addTab(trans.get("pref.dlg.tab.Units"), null, unitsPane(),
73                                 trans.get("pref.dlg.tab.Defaultunits"));
74                 //// Materials and Custom materials
75                 tabbedPane.addTab(trans.get("pref.dlg.tab.Materials"), null, new MaterialEditPanel(),
76                                 trans.get("pref.dlg.tab.Custommaterials"));
77                 //// Options and Miscellaneous options
78                 tabbedPane.addTab(trans.get("pref.dlg.tab.Options"), null, optionsPane(),
79                                 trans.get("pref.dlg.tab.Miscellaneousoptions"));
80                 
81                 //// Close button
82                 JButton close = new JButton(trans.get("dlg.but.close"));
83                 close.addActionListener(new ActionListener() {
84                         @Override
85                         public void actionPerformed(ActionEvent arg0) {
86                                 PreferencesDialog.this.setVisible(false);
87                                 PreferencesDialog.this.dispose();
88                         }
89                 });
90                 panel.add(close, "span, right, tag close");
91                 
92                 this.setContentPane(panel);
93                 pack();
94                 this.setLocationRelativeTo(null);
95                 
96                 this.addWindowListener(new WindowAdapter() {
97                         @Override
98                         public void windowClosed(WindowEvent e) {
99                                 ((SwingPreferences) Application.getPreferences()).storeDefaultUnits();
100                         }
101                 });
102                 
103                 GUIUtil.setDisposableDialogOptions(this, close);
104         }
105         
106         
107         private JPanel optionsPane() {
108                 JPanel panel = new JPanel(new MigLayout("fillx, ins 30lp n n n"));
109                 
110
111                 //// Language selector
112                 Locale userLocale = null;
113                 {
114                         String locale = Application.getPreferences().getString("locale", null);
115                         userLocale = L10N.toLocale(locale);
116                 }
117                 List<Named<Locale>> locales = new ArrayList<Named<Locale>>();
118                 for (Locale l : SwingPreferences.getSupportedLocales()) {
119                         locales.add(new Named<Locale>(l, l.getDisplayLanguage()));
120                 }
121                 Collections.sort(locales);
122                 locales.add(0, new Named<Locale>(null, trans.get("languages.default")));
123                 
124                 final JComboBox languageCombo = new JComboBox(locales.toArray());
125                 for (int i = 0; i < locales.size(); i++) {
126                         if (Utils.equals(userLocale, locales.get(i).get())) {
127                                 languageCombo.setSelectedIndex(i);
128                         }
129                 }
130                 languageCombo.addActionListener(new ActionListener() {
131                         @Override
132                         @SuppressWarnings("unchecked")
133                         public void actionPerformed(ActionEvent e) {
134                                 Named<Locale> selection = (Named<Locale>) languageCombo.getSelectedItem();
135                                 Locale l = selection.get();
136                                 Application.getPreferences().putString(Preferences.USER_LOCAL, l == null ? null : l.toString());
137                         }
138                 });
139                 panel.add(new JLabel(trans.get("lbl.language")), "gapright para");
140                 panel.add(languageCombo, "wrap rel, growx, sg combos");
141                 
142                 panel.add(new StyledLabel(trans.get("PreferencesDialog.lbl.languageEffect"), -3, Style.ITALIC), "span, wrap para*2");
143                 
144
145                 //// Position to insert new body components:
146                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Positiontoinsert")), "gapright para");
147                 panel.add(new JComboBox(new PrefChoiseSelector(Preferences.BODY_COMPONENT_INSERT_POSITION_KEY,
148                                 //// Always ask
149                                 //// Insert in middle
150                                 //// Add to end
151                                 trans.get("pref.dlg.PrefChoiseSelector1"),
152                                 trans.get("pref.dlg.PrefChoiseSelector2"),
153                                 trans.get("pref.dlg.PrefChoiseSelector3"))), "wrap para, growx, sg combos");
154                 
155                 //// Confirm deletion of simulations:
156                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Confirmdeletion")));
157                 panel.add(new JComboBox(new PrefBooleanSelector(Preferences.CONFIRM_DELETE_SIMULATION,
158                                 //// Delete
159                                 //// Confirm
160                                 trans.get("pref.dlg.PrefBooleanSelector1"),
161                                 trans.get("pref.dlg.PrefBooleanSelector2"), true)), "wrap 40lp, growx, sg combos");
162                 
163                 //// User-defined thrust curves:
164                 panel.add(new JLabel(trans.get("pref.dlg.lbl.User-definedthrust")), "spanx, wrap");
165                 final JTextField field = new JTextField();
166                 List<File> files = ((SwingPreferences) Application.getPreferences()).getUserThrustCurveFiles();
167                 String str = "";
168                 for (File file : files) {
169                         if (str.length() > 0) {
170                                 str += ";";
171                         }
172                         str += file.getAbsolutePath();
173                 }
174                 field.setText(str);
175                 field.getDocument().addDocumentListener(new DocumentListener() {
176                         @Override
177                         public void removeUpdate(DocumentEvent e) {
178                                 changed();
179                         }
180                         
181                         @Override
182                         public void insertUpdate(DocumentEvent e) {
183                                 changed();
184                         }
185                         
186                         @Override
187                         public void changedUpdate(DocumentEvent e) {
188                                 changed();
189                         }
190                         
191                         private void changed() {
192                                 String text = field.getText();
193                                 List<File> list = new ArrayList<File>();
194                                 for (String s : text.split(";")) {
195                                         s = s.trim();
196                                         if (s.length() > 0) {
197                                                 list.add(new File(s));
198                                         }
199                                 }
200                                 ((SwingPreferences) Application.getPreferences()).setUserThrustCurveFiles(list);
201                         }
202                 });
203                 panel.add(field, "w 100px, gapright unrel, spanx, growx, split");
204                 
205                 //// Add button
206                 JButton button = new JButton(trans.get("pref.dlg.but.add"));
207                 button.addActionListener(new ActionListener() {
208                         @Override
209                         public void actionPerformed(ActionEvent e) {
210                                 JFileChooser chooser = new JFileChooser();
211                                 SimpleFileFilter filter =
212                                                 new SimpleFileFilter(
213                                                                 //// All thrust curve files (*.eng; *.rse; *.zip; directories)
214                                                                 trans.get("pref.dlg.Allthrustcurvefiles"),
215                                                                 true, "eng", "rse", "zip");
216                                 chooser.addChoosableFileFilter(filter);
217                                 //// RASP motor files (*.eng)
218                                 chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RASPfiles"),
219                                                 true, "eng"));
220                                 //// RockSim engine files (*.rse)
221                                 chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.RockSimfiles"),
222                                                 true, "rse"));
223                                 //// ZIP archives (*.zip)
224                                 chooser.addChoosableFileFilter(new SimpleFileFilter(trans.get("pref.dlg.ZIParchives"),
225                                                 true, "zip"));
226                                 chooser.setFileFilter(filter);
227                                 chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
228                                 if (defaultDirectory != null) {
229                                         chooser.setCurrentDirectory(defaultDirectory);
230                                 }
231                                 
232                                 //// Add
233                                 int returnVal = chooser.showDialog(PreferencesDialog.this, trans.get("pref.dlg.Add"));
234                                 if (returnVal == JFileChooser.APPROVE_OPTION) {
235                                         log.user("Adding user thrust curve: " + chooser.getSelectedFile());
236                                         defaultDirectory = chooser.getCurrentDirectory();
237                                         String text = field.getText().trim();
238                                         if (text.length() > 0) {
239                                                 text += ";";
240                                         }
241                                         text += chooser.getSelectedFile().getAbsolutePath();
242                                         field.setText(text);
243                                 }
244                         }
245                 });
246                 panel.add(button, "gapright unrel");
247                 
248                 //// Reset button
249                 button = new JButton(trans.get("pref.dlg.but.reset"));
250                 
251                 button.addActionListener(new ActionListener() {
252                         @Override
253                         public void actionPerformed(ActionEvent e) {
254                                 // First one sets to the default, but does not un-set the pref
255                                 field.setText(((SwingPreferences)Application.getPreferences()).getDefaultUserThrustCurveFile().getAbsolutePath());
256                                 ((SwingPreferences) Application.getPreferences()).setUserThrustCurveFiles(null);
257                         }
258                 });
259                 panel.add(button, "wrap");
260                 
261                 //// Add directories, RASP motor files (*.eng), RockSim engine files (*.rse) or ZIP archives separated by a semicolon (;) to load external thrust curves.  Changes will take effect the next time you start OpenRocket.
262                 DescriptionArea desc = new DescriptionArea(trans.get("pref.dlg.DescriptionArea.Adddirectories"), 3, -3, false);
263                 desc.setBackground(getBackground());
264                 panel.add(desc, "spanx, growx, wrap 40lp");
265                 
266
267
268                 //// Check for software updates at startup
269                 final JCheckBox softwareUpdateBox =
270                                 new JCheckBox(trans.get("pref.dlg.checkbox.Checkupdates"));
271                 softwareUpdateBox.setSelected( Application.getPreferences().getCheckUpdates());
272                 softwareUpdateBox.addActionListener(new ActionListener() {
273                         @Override
274                         public void actionPerformed(ActionEvent e) {
275                                 Application.getPreferences().setCheckUpdates(softwareUpdateBox.isSelected());
276                         }
277                 });
278                 panel.add(softwareUpdateBox);
279                 
280                 //// Check now button
281                 button = new JButton(trans.get("pref.dlg.but.checknow"));
282                 //// Check for software updates now
283                 button.setToolTipText(trans.get("pref.dlg.ttip.Checkupdatesnow"));
284                 button.addActionListener(new ActionListener() {
285                         @Override
286                         public void actionPerformed(ActionEvent e) {
287                                 checkForUpdates();
288                         }
289                 });
290                 panel.add(button, "right, wrap");
291                 
292
293                 return panel;
294         }
295         
296         private JPanel unitsPane() {
297                 JPanel panel = new JPanel(new MigLayout("", "[][]40lp[][]"));
298                 JComboBox combo;
299                 
300                 //// Select your preferred units:
301                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Selectprefunits")), "span, wrap paragraph");
302                 
303
304                 //// Rocket dimensions:
305                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Rocketdimensions")));
306                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_LENGTH));
307                 panel.add(combo, "sizegroup boxes");
308                 
309                 //// Line density:
310                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Linedensity")));
311                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_LINE));
312                 panel.add(combo, "sizegroup boxes, wrap");
313                 
314
315                 //// Motor dimensions:
316                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Motordimensions")));
317                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MOTOR_DIMENSIONS));
318                 panel.add(combo, "sizegroup boxes");
319                 
320                 //// Surface density:
321                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Surfacedensity")));
322                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_SURFACE));
323                 panel.add(combo, "sizegroup boxes, wrap");
324                 
325
326                 //// Distance:
327                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Distance")));
328                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DISTANCE));
329                 panel.add(combo, "sizegroup boxes");
330                 
331                 //// Bulk density::
332                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Bulkdensity")));
333                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_DENSITY_BULK));
334                 panel.add(combo, "sizegroup boxes, wrap");
335                 
336
337                 //// Velocity:
338                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Velocity")));
339                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_VELOCITY));
340                 panel.add(combo, "sizegroup boxes");
341                 
342                 //// Surface roughness:
343                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Surfaceroughness")));
344                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROUGHNESS));
345                 panel.add(combo, "sizegroup boxes, wrap");
346                 
347
348                 //// Acceleration:
349                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Acceleration")));
350                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ACCELERATION));
351                 panel.add(combo, "sizegroup boxes");
352                 
353                 //// Area:
354                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Area")));
355                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_AREA));
356                 panel.add(combo, "sizegroup boxes, wrap");
357                 
358
359                 //// Mass:
360                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Mass")));
361                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_MASS));
362                 panel.add(combo, "sizegroup boxes");
363                 
364                 //// Angle:
365                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Angle")));
366                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ANGLE));
367                 panel.add(combo, "sizegroup boxes, wrap");
368                 
369
370                 //// Force:
371                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Force")));
372                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_FORCE));
373                 panel.add(combo, "sizegroup boxes");
374                 
375                 //// Roll rate:
376                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Rollrate")));
377                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_ROLL));
378                 panel.add(combo, "sizegroup boxes, wrap");
379                 
380
381                 //// Total impulse:
382                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Totalimpulse")));
383                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_IMPULSE));
384                 panel.add(combo, "sizegroup boxes");
385                 
386                 //// Temperature:
387                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Temperature")));
388                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_TEMPERATURE));
389                 panel.add(combo, "sizegroup boxes, wrap");
390                 
391                 //// Moment of inertia:
392                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Momentofinertia")));
393                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_INERTIA));
394                 panel.add(combo, "sizegroup boxes");
395                 
396                 //// Pressure:
397                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Pressure")));
398                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_PRESSURE));
399                 panel.add(combo, "sizegroup boxes, wrap");
400                 
401
402                 //// Stability:
403                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Stability")));
404                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_STABILITY));
405                 panel.add(combo, "sizegroup boxes");
406                 
407                 //// Windspeed:
408                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Windspeed")));
409                 combo = new JComboBox(new DefaultUnitSelector(UnitGroup.UNITS_WINDSPEED));
410                 panel.add(combo, "sizegroup boxes, wrap para");
411                 
412
413
414
415                 //// Default metric button
416                 JButton button = new JButton(trans.get("pref.dlg.but.defaultmetric"));
417                 button.addActionListener(new ActionListener() {
418                         @Override
419                         public void actionPerformed(ActionEvent e) {
420                                 UnitGroup.setDefaultMetricUnits();
421                                 for (DefaultUnitSelector s : unitSelectors)
422                                         s.fireChange();
423                         }
424                 });
425                 panel.add(button, "spanx, split 2, grow");
426                 
427                 //// Default imperial button
428                 button = new JButton(trans.get("pref.dlg.but.defaultimperial"));
429                 button.addActionListener(new ActionListener() {
430                         @Override
431                         public void actionPerformed(ActionEvent e) {
432                                 UnitGroup.setDefaultImperialUnits();
433                                 for (DefaultUnitSelector s : unitSelectors)
434                                         s.fireChange();
435                         }
436                 });
437                 panel.add(button, "grow, wrap para");
438                 
439                 //// The effects will take place the next time you open a window.
440                 panel.add(new StyledLabel(
441                                 trans.get("pref.dlg.lbl.effect1"), -2, Style.ITALIC),
442                                 "spanx, wrap");
443                 
444
445                 return panel;
446         }
447         
448         
449
450
451
452         private class DefaultUnitSelector extends AbstractListModel implements ComboBoxModel {
453                 
454                 private final UnitGroup group;
455                 
456                 public DefaultUnitSelector(UnitGroup group) {
457                         this.group = group;
458                         unitSelectors.add(this);
459                 }
460                 
461                 @Override
462                 public Object getSelectedItem() {
463                         return group.getDefaultUnit();
464                 }
465                 
466                 @Override
467                 public void setSelectedItem(Object item) {
468                         if (item == null) {
469                                 // Clear selection - huh?
470                                 return;
471                         }
472                         if (!(item instanceof Unit)) {
473                                 throw new IllegalArgumentException("Illegal argument " + item);
474                         }
475                         group.setDefaultUnit(group.getUnitIndex((Unit) item));
476                 }
477                 
478                 @Override
479                 public Object getElementAt(int index) {
480                         return group.getUnit(index);
481                 }
482                 
483                 @Override
484                 public int getSize() {
485                         return group.getUnitCount();
486                 }
487                 
488                 
489                 public void fireChange() {
490                         this.fireContentsChanged(this, 0, this.getSize());
491                 }
492         }
493         
494         
495
496         private class PrefChoiseSelector extends AbstractListModel implements ComboBoxModel {
497                 private final String preference;
498                 private final String[] descriptions;
499                 
500                 public PrefChoiseSelector(String preference, String... descriptions) {
501                         this.preference = preference;
502                         this.descriptions = descriptions;
503                 }
504                 
505                 @Override
506                 public Object getSelectedItem() {
507                         return descriptions[Application.getPreferences().getChoice(preference, descriptions.length, 0)];
508                 }
509                 
510                 @Override
511                 public void setSelectedItem(Object item) {
512                         if (item == null) {
513                                 // Clear selection - huh?
514                                 return;
515                         }
516                         if (!(item instanceof String)) {
517                                 throw new IllegalArgumentException("Illegal argument " + item);
518                         }
519                         int index;
520                         for (index = 0; index < descriptions.length; index++) {
521                                 if (((String) item).equalsIgnoreCase(descriptions[index]))
522                                         break;
523                         }
524                         if (index >= descriptions.length) {
525                                 throw new IllegalArgumentException("Illegal argument " + item);
526                         }
527                         
528                         Application.getPreferences().putChoice(preference, index);
529                 }
530                 
531                 @Override
532                 public Object getElementAt(int index) {
533                         return descriptions[index];
534                 }
535                 
536                 @Override
537                 public int getSize() {
538                         return descriptions.length;
539                 }
540         }
541         
542         
543         private class PrefBooleanSelector extends AbstractListModel implements ComboBoxModel {
544                 private final String preference;
545                 private final String trueDesc, falseDesc;
546                 private final boolean def;
547                 
548                 public PrefBooleanSelector(String preference, String falseDescription,
549                                 String trueDescription, boolean defaultState) {
550                         this.preference = preference;
551                         this.trueDesc = trueDescription;
552                         this.falseDesc = falseDescription;
553                         this.def = defaultState;
554                 }
555                 
556                 @Override
557                 public Object getSelectedItem() {
558                         if (Application.getPreferences().getBoolean(preference, def)) {
559                                 return trueDesc;
560                         } else {
561                                 return falseDesc;
562                         }
563                 }
564                 
565                 @Override
566                 public void setSelectedItem(Object item) {
567                         if (item == null) {
568                                 // Clear selection - huh?
569                                 return;
570                         }
571                         if (!(item instanceof String)) {
572                                 throw new IllegalArgumentException("Illegal argument " + item);
573                         }
574                         
575                         if (trueDesc.equals(item)) {
576                                 Application.getPreferences().putBoolean(preference, true);
577                         } else if (falseDesc.equals(item)) {
578                                 Application.getPreferences().putBoolean(preference, false);
579                         } else {
580                                 throw new IllegalArgumentException("Illegal argument " + item);
581                         }
582                 }
583                 
584                 @Override
585                 public Object getElementAt(int index) {
586                         switch (index) {
587                         case 0:
588                                 return def ? trueDesc : falseDesc;
589                                 
590                         case 1:
591                                 return def ? falseDesc : trueDesc;
592                                 
593                         default:
594                                 throw new IndexOutOfBoundsException("Boolean asked for index=" + index);
595                         }
596                 }
597                 
598                 @Override
599                 public int getSize() {
600                         return 2;
601                 }
602         }
603         
604         
605         private void checkForUpdates() {
606                 final UpdateInfoRetriever retriever = new UpdateInfoRetriever();
607                 retriever.start();
608                 
609
610                 // Progress dialog
611                 final JDialog dialog = new JDialog(this, ModalityType.APPLICATION_MODAL);
612                 JPanel panel = new JPanel(new MigLayout());
613                 
614                 //// Checking for updates...
615                 panel.add(new JLabel(trans.get("pref.dlg.lbl.Checkingupdates")), "wrap");
616                 
617                 JProgressBar bar = new JProgressBar();
618                 bar.setIndeterminate(true);
619                 panel.add(bar, "growx, wrap para");
620                 
621                 //// Cancel button
622                 JButton cancel = new JButton(trans.get("dlg.but.cancel"));
623                 cancel.addActionListener(new ActionListener() {
624                         @Override
625                         public void actionPerformed(ActionEvent e) {
626                                 dialog.dispose();
627                         }
628                 });
629                 panel.add(cancel, "right");
630                 dialog.add(panel);
631                 
632                 GUIUtil.setDisposableDialogOptions(dialog, cancel);
633                 
634
635                 // Timer to monitor progress
636                 final Timer timer = new Timer(100, null);
637                 final long startTime = System.currentTimeMillis();
638                 
639                 ActionListener listener = new ActionListener() {
640                         @Override
641                         public void actionPerformed(ActionEvent e) {
642                                 if (!retriever.isRunning() || startTime + 10000 < System.currentTimeMillis()) {
643                                         timer.stop();
644                                         dialog.dispose();
645                                 }
646                         }
647                 };
648                 timer.addActionListener(listener);
649                 timer.start();
650                 
651
652                 // Wait for action
653                 dialog.setVisible(true);
654                 
655
656                 // Check result
657                 UpdateInfo info = retriever.getUpdateInfo();
658                 if (info == null) {
659                         JOptionPane.showMessageDialog(this,
660                                         //// An error occurred while communicating with the server.
661                                         trans.get("pref.dlg.lbl.msg1"),
662                                         //// Unable to retrieve update information
663                                         trans.get("pref.dlg.lbl.msg2"), JOptionPane.WARNING_MESSAGE, null);
664                 } else if (info.getLatestVersion() == null ||
665                                 info.getLatestVersion().equals("") ||
666                                 BuildProperties.getVersion().equalsIgnoreCase(info.getLatestVersion())) {
667                         JOptionPane.showMessageDialog(this,
668                                         //// You are running the latest version of OpenRocket.
669                                         trans.get("pref.dlg.lbl.msg3"),
670                                         //// No updates available
671                                         trans.get("pref.dlg.lbl.msg4"), JOptionPane.INFORMATION_MESSAGE, null);
672                 } else {
673                         UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
674                         infoDialog.setVisible(true);
675                         if (infoDialog.isReminderSelected()) {
676                                 Application.getPreferences().putString(SwingPreferences.LAST_UPDATE, "");
677                         } else {
678                                 Application.getPreferences().putString(SwingPreferences.LAST_UPDATE, info.getLatestVersion());
679                         }
680                 }
681                 
682         }
683         
684         
685         ////////  Singleton implementation  ////////
686         
687         private static PreferencesDialog dialog = null;
688         
689         public static void showPreferences(Window parent) {
690                 if (dialog != null) {
691                         dialog.dispose();
692                 }
693                 dialog = new PreferencesDialog(parent);
694                 dialog.setVisible(true);
695         }
696         
697
698 }