b2e13195e49ca97c153567b9195a96dea3210d1e
[debian/openrocket] / core / src / net / sf / openrocket / startup / Startup2.java
1 package net.sf.openrocket.startup;
2
3 import java.awt.GraphicsEnvironment;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.io.File;
7
8 import javax.swing.SwingUtilities;
9 import javax.swing.Timer;
10 import javax.swing.ToolTipManager;
11
12 import net.sf.openrocket.communication.UpdateInfo;
13 import net.sf.openrocket.communication.UpdateInfoRetriever;
14 import net.sf.openrocket.database.ComponentPresetDatabase;
15 import net.sf.openrocket.database.Databases;
16 import net.sf.openrocket.gui.dialogs.UpdateInfoDialog;
17 import net.sf.openrocket.gui.main.BasicFrame;
18 import net.sf.openrocket.gui.main.Splash;
19 import net.sf.openrocket.gui.main.SwingExceptionHandler;
20 import net.sf.openrocket.gui.util.GUIUtil;
21 import net.sf.openrocket.gui.util.SwingPreferences;
22 import net.sf.openrocket.logging.LogHelper;
23 import net.sf.openrocket.util.BuildProperties;
24
25 /**
26  * The second class in the OpenRocket startup sequence.  This class can assume the
27  * Application class to be properly set up, and can use any classes safely.
28  * 
29  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
30  */
31 public class Startup2 {
32         private static final LogHelper log = Application.getLogger();
33         
34
35         private static final String THRUSTCURVE_DIRECTORY = "datafiles/thrustcurves/";
36         
37         /**
38          * Run when starting up OpenRocket after Application has been set up.
39          * 
40          * @param args  command line arguments
41          */
42         static void runMain(final String[] args) throws Exception {
43                 
44                 log.info("Starting up OpenRocket version " + BuildProperties.getVersion());
45                 
46                 // Check that we're not running headless
47                 log.info("Checking for graphics head");
48                 checkHead();
49                 
50                 // Check that we're running a good version of a JRE
51                 log.info("Checking JRE compatibility");
52                 VersionHelper.checkVersion();
53                 VersionHelper.checkOpenJDK();
54                 
55                 // Run the actual startup method in the EDT since it can use progress dialogs etc.
56                 log.info("Moving startup to EDT");
57                 SwingUtilities.invokeAndWait(new Runnable() {
58                         @Override
59                         public void run() {
60                                 runInEDT(args);
61                         }
62                 });
63                 
64                 log.info("Startup complete");
65         }
66         
67         
68         /**
69          * Run in the EDT when starting up OpenRocket.
70          * 
71          * @param args  command line arguments
72          */
73         private static void runInEDT(String[] args) {
74                 
75                 // Initialize the splash screen with version info
76                 log.info("Initializing the splash screen");
77                 Splash.init();
78                 
79                 // Must be done after localization is initialized
80                 ComponentPresetDatabase componentPresetDao = new ComponentPresetDatabase();
81                 ConcurrentComponentPresetDatabaseLoader presetLoader = new ConcurrentComponentPresetDatabaseLoader( componentPresetDao );
82                 presetLoader.load();
83                 
84                 Application.setComponentPresetDao( componentPresetDao );
85                 
86                 // Setup the uncaught exception handler
87                 log.info("Registering exception handler");
88                 SwingExceptionHandler exceptionHandler = new SwingExceptionHandler();
89                 Application.setExceptionHandler(exceptionHandler);
90                 exceptionHandler.registerExceptionHandler();
91                 
92                 // Start update info fetching
93                 final UpdateInfoRetriever updateInfo;
94                 if ( Application.getPreferences().getCheckUpdates()) {
95                         log.info("Starting update check");
96                         updateInfo = new UpdateInfoRetriever();
97                         updateInfo.start();
98                 } else {
99                         log.info("Update check disabled");
100                         updateInfo = null;
101                 }
102                 
103                 // Set the best available look-and-feel
104                 log.info("Setting best LAF");
105                 GUIUtil.setBestLAF();
106                 
107                 // Set tooltip delay time.  Tooltips are used in MotorChooserDialog extensively.
108                 ToolTipManager.sharedInstance().setDismissDelay(30000);
109                 
110                 // Load defaults
111                 ((SwingPreferences) Application.getPreferences()).loadDefaultUnits();
112                 
113                 // Load motors etc.
114                 log.info("Loading databases");
115                 
116                 ConcurrentLoadingThrustCurveMotorSetDatabase motorLoader = new ConcurrentLoadingThrustCurveMotorSetDatabase(THRUSTCURVE_DIRECTORY);
117                 motorLoader.startLoading();
118                 Application.setMotorSetDatabase(motorLoader);
119
120                 Databases.fakeMethod();
121                 
122                 try {
123                         presetLoader.await();
124                 } catch ( InterruptedException iex) {
125                         
126                 }
127
128                 // Starting action (load files or open new document)
129                 log.info("Opening main application window");
130                 if (!handleCommandLine(args)) {
131                         BasicFrame.newAction();
132                 }
133                 
134                 // Check whether update info has been fetched or whether it needs more time
135                 log.info("Checking update status");
136                 checkUpdateStatus(updateInfo);
137                 
138         }
139         
140         
141         /**
142          * Check that the JRE is not running headless.
143          */
144         private static void checkHead() {
145                 
146                 if (GraphicsEnvironment.isHeadless()) {
147                         log.error("Application is headless.");
148                         System.err.println();
149                         System.err.println("OpenRocket cannot currently be run without the graphical " +
150                                         "user interface.");
151                         System.err.println();
152                         System.exit(1);
153                 }
154                 
155         }
156         
157         
158         private static void checkUpdateStatus(final UpdateInfoRetriever updateInfo) {
159                 if (updateInfo == null)
160                         return;
161                 
162                 int delay = 1000;
163                 if (!updateInfo.isRunning())
164                         delay = 100;
165                 
166                 final Timer timer = new Timer(delay, null);
167                 
168                 ActionListener listener = new ActionListener() {
169                         private int count = 5;
170                         
171                         @Override
172                         public void actionPerformed(ActionEvent e) {
173                                 if (!updateInfo.isRunning()) {
174                                         timer.stop();
175                                         
176                                         String current = BuildProperties.getVersion();
177                                         String last = Application.getPreferences().getString(Preferences.LAST_UPDATE, "");
178                                         
179                                         UpdateInfo info = updateInfo.getUpdateInfo();
180                                         if (info != null && info.getLatestVersion() != null &&
181                                                         !current.equals(info.getLatestVersion()) &&
182                                                         !last.equals(info.getLatestVersion())) {
183                                                 
184                                                 UpdateInfoDialog infoDialog = new UpdateInfoDialog(info);
185                                                 infoDialog.setVisible(true);
186                                                 if (infoDialog.isReminderSelected()) {
187                                                         Application.getPreferences().putString(Preferences.LAST_UPDATE, "");
188                                                 } else {
189                                                         Application.getPreferences().putString(Preferences.LAST_UPDATE, info.getLatestVersion());
190                                                 }
191                                         }
192                                 }
193                                 count--;
194                                 if (count <= 0)
195                                         timer.stop();
196                         }
197                 };
198                 timer.addActionListener(listener);
199                 timer.start();
200         }
201         
202         /**
203          * Handles arguments passed from the command line.  This may be used either
204          * when starting the first instance of OpenRocket or later when OpenRocket is
205          * executed again while running.
206          * 
207          * @param args  the command-line arguments.
208          * @return              whether a new frame was opened or similar user desired action was
209          *                              performed as a result.
210          */
211         private static boolean handleCommandLine(String[] args) {
212                 
213                 // Check command-line for files
214                 boolean opened = false;
215                 for (String file : args) {
216                         if (BasicFrame.open(new File(file), null)) {
217                                 opened = true;
218                         }
219                 }
220                 return opened;
221         }
222         
223 }