source: josm/trunk/src/org/openstreetmap/josm/gui/MainApplication.java@ 4720

Last change on this file since 4720 was 4720, checked in by jttt, 12 years ago

Register EDT checker (by default only for locally compiled josm). It will print stacktrace when something tries to access gui from non EDT thread

  • Property svn:eol-style set to native
File size: 14.6 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Image;
8import java.awt.Toolkit;
9import java.awt.event.WindowAdapter;
10import java.awt.event.WindowEvent;
11import java.io.File;
12import java.net.Authenticator;
13import java.net.ProxySelector;
14import java.security.AllPermission;
15import java.security.CodeSource;
16import java.security.PermissionCollection;
17import java.security.Permissions;
18import java.security.Policy;
19import java.util.Collection;
20import java.util.HashMap;
21import java.util.LinkedList;
22import java.util.List;
23import java.util.Map;
24
25import javax.swing.JFrame;
26import javax.swing.RepaintManager;
27import javax.swing.SwingUtilities;
28
29import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
30import org.openstreetmap.josm.Main;
31import org.openstreetmap.josm.data.AutosaveTask;
32import org.openstreetmap.josm.data.Preferences;
33import org.openstreetmap.josm.data.Version;
34import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
35import org.openstreetmap.josm.gui.progress.ProgressMonitor;
36import org.openstreetmap.josm.io.DefaultProxySelector;
37import org.openstreetmap.josm.io.auth.CredentialsManager;
38import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
39import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
40import org.openstreetmap.josm.plugins.PluginHandler;
41import org.openstreetmap.josm.plugins.PluginInformation;
42import org.openstreetmap.josm.tools.BugReportExceptionHandler;
43import org.openstreetmap.josm.tools.I18n;
44import org.openstreetmap.josm.tools.ImageProvider;
45
46/**
47 * Main window class application.
48 *
49 * @author imi
50 */
51public class MainApplication extends Main {
52 /**
53 * Allow subclassing (see JOSM.java)
54 */
55 public MainApplication() {}
56
57 /**
58 * Construct an main frame, ready sized and operating. Does not
59 * display the frame.
60 */
61 public MainApplication(JFrame mainFrame) {
62 super();
63 mainFrame.setContentPane(contentPanePrivate);
64 mainFrame.setJMenuBar(menu);
65 mainFrame.setBounds(bounds);
66 LinkedList<Image> l = new LinkedList<Image>();
67 l.add(ImageProvider.get("logo_16x16x32").getImage());
68 l.add(ImageProvider.get("logo_16x16x8").getImage());
69 l.add(ImageProvider.get("logo_32x32x32").getImage());
70 l.add(ImageProvider.get("logo_32x32x8").getImage());
71 l.add(ImageProvider.get("logo_48x48x32").getImage());
72 l.add(ImageProvider.get("logo_48x48x8").getImage());
73 l.add(ImageProvider.get("logo").getImage());
74 //mainFrame.setIconImage(ImageProvider.get("logo").getImage());
75 mainFrame.setIconImages(l);
76 mainFrame.addWindowListener(new WindowAdapter(){
77 @Override public void windowClosing(final WindowEvent arg0) {
78 Main.exitJosm(true);
79 }
80 });
81 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
82 }
83
84 /**
85 * Displays help on the console
86 *
87 */
88 public static void showHelp() {
89 // TODO: put in a platformHook for system that have no console by default
90 System.out.println(tr("Java OpenStreetMap Editor")+"\n\n"+
91 tr("usage")+":\n"+
92 "\tjava -jar josm.jar <options>...\n\n"+
93 tr("options")+":\n"+
94 "\t--help|-?|-h "+tr("Show this help")+"\n"+
95 "\t--geometry=widthxheight(+|-)x(+|-)y "+tr("Standard unix geometry argument")+"\n"+
96 "\t[--download=]minlat,minlon,maxlat,maxlon "+tr("Download the bounding box")+"\n"+
97 "\t[--download=]<url> "+tr("Download the location at the url (with lat=x&lon=y&zoom=z)")+"\n"+
98 "\t[--download=]<filename> "+tr("Open a file (any file type that can be opened with File/Open)")+"\n"+
99 "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw gps")+"\n"+
100 "\t--downloadgps=<url> "+tr("Download the location at the url (with lat=x&lon=y&zoom=z) as raw gps")+"\n"+
101 "\t--selection=<searchstring> "+tr("Select with the given search")+"\n"+
102 "\t--[no-]maximize "+tr("Launch in maximized mode")+"\n"+
103 "\t--reset-preferences "+tr("Reset the preferences to default")+"\n\n"+
104 "\t--language=<language> "+tr("Set the language")+"\n\n"+
105 tr("options provided as Java system properties")+":\n"+
106 "\t-Djosm.home="+tr("/PATH/TO/JOSM/FOLDER/ ")+tr("Change the folder for all user settings")+"\n\n"+
107 tr("note: For some tasks, JOSM needs a lot of memory. It can be necessary to add the following\n" +
108 " Java option to specify the maximum size of allocated memory in megabytes")+":\n"+
109 "\t-Xmx...m\n\n"+
110 tr("examples")+":\n"+
111 "\tjava -jar josm.jar track1.gpx track2.gpx london.osm\n"+
112 "\tjava -jar josm.jar http://www.openstreetmap.org/index.html?lat=43.2&lon=11.1&zoom=13\n"+
113 "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
114 "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n"+
115 "\tjava -Djosm.home=/home/user/.josm_dev -jar josm.jar\n"+
116 "\tjava -Xmx400m -jar josm.jar\n\n"+
117 tr("Parameters --download, --downloadgps, and --selection are processed in this order.")+"\n"+
118 tr("Make sure you load some data if you use --selection.")+"\n"
119 );
120 }
121
122 private static Map<String, Collection<String>> buildCommandLineArgumentMap(String[] args) {
123 Map<String, Collection<String>> argMap = new HashMap<String, Collection<String>>();
124 for (String arg : args) {
125 if ("-h".equals(arg) || "-?".equals(arg)) {
126 arg = "--help";
127 } else if ("-v".equals(arg)) {
128 arg = "--version";
129 }
130 // handle simple arguments like file names, URLs, bounds
131 if (!arg.startsWith("--")) {
132 arg = "--download="+arg;
133 }
134 int i = arg.indexOf('=');
135 String key = i == -1 ? arg.substring(2) : arg.substring(2,i);
136 String value = i == -1 ? "" : arg.substring(i+1);
137 Collection<String> v = argMap.get(key);
138 if (v == null) {
139 v = new LinkedList<String>();
140 }
141 v.add(value);
142 argMap.put(key, v);
143 }
144 return argMap;
145 }
146
147 /**
148 * Main application Startup
149 */
150 public static void main(final String[] argArray) {
151 I18n.init();
152 Main.checkJava6();
153 Main.pref = new Preferences();
154
155 Policy.setPolicy(new Policy() {
156 // Permissions for plug-ins loaded when josm is started via webstart
157 private PermissionCollection pc;
158
159 {
160 pc = new Permissions();
161 pc.add(new AllPermission());
162 }
163
164 @Override
165 public void refresh() { }
166
167 @Override
168 public PermissionCollection getPermissions(CodeSource codesource) {
169 return pc;
170 }
171 });
172
173 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
174 // http://stuffthathappens.com/blog/2007/10/15/one-more-note-on-uncaught-exception-handlers/
175 System.setProperty("sun.awt.exception.handler", BugReportExceptionHandler.class.getName());
176
177 // initialize the platform hook, and
178 Main.determinePlatformHook();
179 // call the really early hook before we do anything else
180 Main.platform.preStartupHook();
181
182 // construct argument table
183 final Map<String, Collection<String>> args = buildCommandLineArgumentMap(argArray);
184
185 if (args.containsKey("version")) {
186 System.out.println(Version.getInstance().getAgentString());
187 System.exit(0);
188 } else {
189 System.out.println(Version.getInstance().getReleaseAttributes());
190 }
191
192 Main.pref.init(args.containsKey("reset-preferences"));
193
194 // Check if passed as parameter
195 if (args.containsKey("language")) {
196 I18n.set((String)(args.get("language").toArray()[0]));
197 } else {
198 I18n.set(Main.pref.get("language", null));
199 }
200 Main.pref.updateSystemProperties();
201
202 DefaultAuthenticator.createInstance();
203 Authenticator.setDefault(DefaultAuthenticator.getInstance());
204 ProxySelector.setDefault(new DefaultProxySelector(ProxySelector.getDefault()));
205 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
206
207 // asking for help? show help and exit
208 if (args.containsKey("help")) {
209 showHelp();
210 System.exit(0);
211 }
212
213 SplashScreen splash = new SplashScreen();
214 final ProgressMonitor monitor = splash.getProgressMonitor();
215 monitor.beginTask(tr("Initializing"));
216 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
217 Main.setInitStatusListener(new InitStatusListener() {
218
219 @Override
220 public void updateStatus(String event) {
221 monitor.indeterminateSubTask(event);
222 }
223 });
224
225 List<PluginInformation> pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash,monitor.createSubTaskMonitor(1, false));
226 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
227 monitor.subTask(tr("Updating plugins"));
228 pluginsToLoad = PluginHandler.updatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
229 }
230
231 monitor.indeterminateSubTask(tr("Installing updated plugins"));
232 PluginHandler.installDownloadedPlugins(true);
233
234 monitor.indeterminateSubTask(tr("Loading early plugins"));
235 PluginHandler.loadEarlyPlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
236
237 monitor.indeterminateSubTask(tr("Setting defaults"));
238 preConstructorInit(args);
239 removeObsoletePreferences();
240
241 monitor.indeterminateSubTask(tr("Creating main GUI"));
242 JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
243 Main.parent = mainFrame;
244 Main.addListener();
245 final Main main = new MainApplication(mainFrame);
246
247 monitor.indeterminateSubTask(tr("Loading plugins"));
248 PluginHandler.loadLatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
249 toolbar.refreshToolbarControl();
250 splash.setVisible(false);
251 splash.dispose();
252 mainFrame.setVisible(true);
253
254 boolean maximized = Boolean.parseBoolean(Main.pref.get("gui.maximized"));
255 if ((!args.containsKey("no-maximize") && maximized) || args.containsKey("maximize")) {
256 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
257 // Main.debug("Main window maximized");
258 Main.windowState = JFrame.MAXIMIZED_BOTH;
259 mainFrame.setExtendedState(Main.windowState);
260 } else {
261 Main.debug("Main window: maximizing not supported");
262 }
263 } else {
264 // Main.debug("Main window not maximized");
265 }
266 if(main.menu.fullscreenToggleAction != null) {
267 main.menu.fullscreenToggleAction.initial();
268 }
269
270 SwingUtilities.invokeLater(new Runnable() {
271 public void run() {
272 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
273 AutosaveTask autosaveTask = new AutosaveTask();
274 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
275 if (!unsavedLayerFiles.isEmpty()) {
276 ExtendedDialog dialog = new ExtendedDialog(
277 Main.parent,
278 tr("Unsaved osm data"),
279 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
280 );
281 dialog.setContent(
282 trn("JOSM found {0} unsaved osm data layer. ",
283 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
284 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
285 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/remove"});
286 int selection = dialog.showDialog().getValue();
287 if (selection == 1) {
288 autosaveTask.recoverUnsavedLayers();
289 } else if (selection == 3) {
290 autosaveTask.dicardUnsavedLayers();
291 }
292 }
293 autosaveTask.schedule();
294 }
295
296 main.postConstructorProcessCmdLine(args);
297
298 }
299 });
300
301 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
302 RemoteControl.start();
303 }
304
305 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
306 // Repaint manager is registered so late for a reason - there is lots of violation during startup process but they don't seem to break anything and are difficult to fix
307 System.out.println("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to conosole");
308 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
309 }
310
311 }
312
313 /**
314 * Removes obsolete preference settings. If you throw out a once-used preference
315 * setting, add it to the list here with an expiry date (written as comment). If you
316 * see something with an expiry date in the past, remove it from the list.
317 */
318 public static void removeObsoletePreferences() {
319
320 String[] obsolete = {
321 "edit.make-parallel-way-action.snap-threshold" // 10/2011 - replaced by snap-threshold-percent. Can be removed mid 2012
322 };
323 for (String key : obsolete) {
324 if (Main.pref.hasKey(key)) {
325 Main.pref.removeFromCollection(key, Main.pref.get(key));
326 System.out.println(tr("Preference setting {0} has been removed since it is no longer used.", key));
327 }
328 }
329 }
330}
Note: See TracBrowser for help on using the repository browser.