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