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

Last change on this file since 7509 was 7493, checked in by Don-vip, 10 years ago

fix HeadlessException when running java -jar josm.jar --help

  • Property svn:eol-style set to native
File size: 26.2 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6import gnu.getopt.Getopt;
7import gnu.getopt.LongOpt;
8
9import java.awt.Dimension;
10import java.awt.Image;
11import java.awt.Toolkit;
12import java.awt.event.WindowAdapter;
13import java.awt.event.WindowEvent;
14import java.io.File;
15import java.io.IOException;
16import java.io.InputStream;
17import java.net.Authenticator;
18import java.net.ProxySelector;
19import java.net.URL;
20import java.security.AllPermission;
21import java.security.CodeSource;
22import java.security.KeyStoreException;
23import java.security.NoSuchAlgorithmException;
24import java.security.PermissionCollection;
25import java.security.Permissions;
26import java.security.Policy;
27import java.security.cert.CertificateException;
28import java.util.ArrayList;
29import java.util.Arrays;
30import java.util.Collection;
31import java.util.HashMap;
32import java.util.LinkedList;
33import java.util.List;
34import java.util.Map;
35import java.util.Set;
36import java.util.TreeSet;
37
38import javax.swing.JFrame;
39import javax.swing.JOptionPane;
40import javax.swing.RepaintManager;
41import javax.swing.SwingUtilities;
42
43import org.jdesktop.swinghelper.debug.CheckThreadViolationRepaintManager;
44import org.openstreetmap.josm.Main;
45import org.openstreetmap.josm.actions.PreferencesAction;
46import org.openstreetmap.josm.data.AutosaveTask;
47import org.openstreetmap.josm.data.CustomConfigurator;
48import org.openstreetmap.josm.data.Preferences;
49import org.openstreetmap.josm.data.Version;
50import org.openstreetmap.josm.gui.download.DownloadDialog;
51import org.openstreetmap.josm.gui.preferences.server.OAuthAccessTokenHolder;
52import org.openstreetmap.josm.gui.preferences.server.ProxyPreference;
53import org.openstreetmap.josm.gui.progress.ProgressMonitor;
54import org.openstreetmap.josm.gui.util.GuiHelper;
55import org.openstreetmap.josm.io.DefaultProxySelector;
56import org.openstreetmap.josm.io.MessageNotifier;
57import org.openstreetmap.josm.io.OnlineResource;
58import org.openstreetmap.josm.io.auth.CredentialsManager;
59import org.openstreetmap.josm.io.auth.DefaultAuthenticator;
60import org.openstreetmap.josm.io.remotecontrol.RemoteControl;
61import org.openstreetmap.josm.plugins.PluginHandler;
62import org.openstreetmap.josm.plugins.PluginInformation;
63import org.openstreetmap.josm.tools.BugReportExceptionHandler;
64import org.openstreetmap.josm.tools.FontsManager;
65import org.openstreetmap.josm.tools.I18n;
66import org.openstreetmap.josm.tools.ImageProvider;
67import org.openstreetmap.josm.tools.OsmUrlToBounds;
68import org.openstreetmap.josm.tools.PlatformHookWindows;
69import org.openstreetmap.josm.tools.Utils;
70
71/**
72 * Main window class application.
73 *
74 * @author imi
75 */
76public class MainApplication extends Main {
77 /**
78 * Allow subclassing (see JOSM.java)
79 */
80 public MainApplication() {}
81
82 /**
83 * Constructs a main frame, ready sized and operating. Does not display the frame.
84 * @param mainFrame The main JFrame of the application
85 */
86 public MainApplication(JFrame mainFrame) {
87 addListener();
88 mainFrame.setContentPane(contentPanePrivate);
89 mainFrame.setJMenuBar(menu);
90 geometry.applySafe(mainFrame);
91 List<Image> l = new LinkedList<>();
92 l.add(ImageProvider.get("logo_16x16x32").getImage());
93 l.add(ImageProvider.get("logo_16x16x8").getImage());
94 l.add(ImageProvider.get("logo_32x32x32").getImage());
95 l.add(ImageProvider.get("logo_32x32x8").getImage());
96 l.add(ImageProvider.get("logo_48x48x32").getImage());
97 l.add(ImageProvider.get("logo_48x48x8").getImage());
98 l.add(ImageProvider.get("logo").getImage());
99 mainFrame.setIconImages(l);
100 mainFrame.addWindowListener(new WindowAdapter(){
101 @Override
102 public void windowClosing(final WindowEvent arg0) {
103 Main.exitJosm(true, 0);
104 }
105 });
106 mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
107 }
108
109 /**
110 * Displays help on the console
111 * @since 2748
112 */
113 public static void showHelp() {
114 // TODO: put in a platformHook for system that have no console by default
115 System.out.println(tr("Java OpenStreetMap Editor")+" ["
116 +Version.getInstance().getAgentString()+"]\n\n"+
117 tr("usage")+":\n"+
118 "\tjava -jar josm.jar <options>...\n\n"+
119 tr("options")+":\n"+
120 "\t--help|-h "+tr("Show this help")+"\n"+
121 "\t--geometry=widthxheight(+|-)x(+|-)y "+tr("Standard unix geometry argument")+"\n"+
122 "\t[--download=]minlat,minlon,maxlat,maxlon "+tr("Download the bounding box")+"\n"+
123 "\t[--download=]<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z)")+"\n"+
124 "\t[--download=]<filename> "+tr("Open a file (any file type that can be opened with File/Open)")+"\n"+
125 "\t--downloadgps=minlat,minlon,maxlat,maxlon "+tr("Download the bounding box as raw GPS")+"\n"+
126 "\t--downloadgps=<URL> "+tr("Download the location at the URL (with lat=x&lon=y&zoom=z) as raw GPS")+"\n"+
127 "\t--selection=<searchstring> "+tr("Select with the given search")+"\n"+
128 "\t--[no-]maximize "+tr("Launch in maximized mode")+"\n"+
129 "\t--reset-preferences "+tr("Reset the preferences to default")+"\n\n"+
130 "\t--load-preferences=<url-to-xml> "+tr("Changes preferences according to the XML file")+"\n\n"+
131 "\t--set=<key>=<value> "+tr("Set preference key to value")+"\n\n"+
132 "\t--language=<language> "+tr("Set the language")+"\n\n"+
133 "\t--version "+tr("Displays the JOSM version and exits")+"\n\n"+
134 "\t--debug "+tr("Print debugging messages to console")+"\n\n"+
135 "\t--offline=<osm_api|josm_website|all> "+tr("Disable access to the given resource(s), separated by comma")+"\n\n"+
136 tr("options provided as Java system properties")+":\n"+
137 "\t-Djosm.home="+tr("/PATH/TO/JOSM/FOLDER/ ")+tr("Change the folder for all user settings")+"\n\n"+
138 tr("note: For some tasks, JOSM needs a lot of memory. It can be necessary to add the following\n" +
139 " Java option to specify the maximum size of allocated memory in megabytes")+":\n"+
140 "\t-Xmx...m\n\n"+
141 tr("examples")+":\n"+
142 "\tjava -jar josm.jar track1.gpx track2.gpx london.osm\n"+
143 "\tjava -jar josm.jar "+OsmUrlToBounds.getURL(43.2, 11.1, 13)+"\n"+
144 "\tjava -jar josm.jar london.osm --selection=http://www.ostertag.name/osm/OSM_errors_node-duplicate.xml\n"+
145 "\tjava -jar josm.jar 43.2,11.1,43.4,11.4\n"+
146 "\tjava -Djosm.home=/home/user/.josm_dev -jar josm.jar\n"+
147 "\tjava -Xmx1024m -jar josm.jar\n\n"+
148 tr("Parameters --download, --downloadgps, and --selection are processed in this order.")+"\n"+
149 tr("Make sure you load some data if you use --selection.")+"\n"
150 );
151 }
152
153 /**
154 * JOSM command line options.
155 * @see <a href="https://josm.openstreetmap.de/wiki/Help/CommandLineOptions">Help/CommandLineOptions</a>
156 * @since 5279
157 */
158 public enum Option {
159 /** --help|-h Show this help */
160 HELP(false),
161 /** --version Displays the JOSM version and exits */
162 VERSION(false),
163 /** --debug Print debugging messages to console */
164 DEBUG(false),
165 /** --trace Print detailed debugging messages to console */
166 TRACE(false),
167 /** --language=&lt;language&gt; Set the language */
168 LANGUAGE(true),
169 /** --reset-preferences Reset the preferences to default */
170 RESET_PREFERENCES(false),
171 /** --load-preferences=&lt;url-to-xml&gt; Changes preferences according to the XML file */
172 LOAD_PREFERENCES(true),
173 /** --set=&lt;key&gt;=&lt;value&gt; Set preference key to value */
174 SET(true),
175 /** --geometry=widthxheight(+|-)x(+|-)y Standard unix geometry argument */
176 GEOMETRY(true),
177 /** --no-maximize Do not launch in maximized mode */
178 NO_MAXIMIZE(false),
179 /** --maximize Launch in maximized mode */
180 MAXIMIZE(false),
181 /** --download=minlat,minlon,maxlat,maxlon Download the bounding box <br>
182 * --download=&lt;URL&gt; Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) <br>
183 * --download=&lt;filename&gt; Open a file (any file type that can be opened with File/Open) */
184 DOWNLOAD(true),
185 /** --downloadgps=minlat,minlon,maxlat,maxlon Download the bounding box as raw GPS <br>
186 * --downloadgps=&lt;URL&gt; Download the location at the URL (with lat=x&amp;lon=y&amp;zoom=z) as raw GPS */
187 DOWNLOADGPS(true),
188 /** --selection=&lt;searchstring&gt; Select with the given search */
189 SELECTION(true),
190 /** --offline=&lt;osm_api|josm_website|all&gt; Disable access to the given resource(s), delimited by comma */
191 OFFLINE(true);
192
193 private String name;
194 private boolean requiresArgument;
195
196 private Option(boolean requiresArgument) {
197 this.name = name().toLowerCase().replace("_", "-");
198 this.requiresArgument = requiresArgument;
199 }
200
201 /**
202 * Replies the option name
203 * @return The option name, in lowercase
204 */
205 public String getName() {
206 return name;
207 }
208
209 /**
210 * Determines if this option requires an argument.
211 * @return {@code true} if this option requires an argument, {@code false} otherwise
212 */
213 public boolean requiresArgument() {
214 return requiresArgument;
215 }
216
217 public static Map<Option, Collection<String>> fromStringMap(Map<String, Collection<String>> opts) {
218 Map<Option, Collection<String>> res = new HashMap<>();
219 for (Map.Entry<String, Collection<String>> e : opts.entrySet()) {
220 Option o = Option.valueOf(e.getKey().toUpperCase().replace("-", "_"));
221 if (o != null) {
222 res.put(o, e.getValue());
223 }
224 }
225 return res;
226 }
227 }
228
229 private static Map<Option, Collection<String>> buildCommandLineArgumentMap(String[] args) {
230
231 List<LongOpt> los = new ArrayList<>();
232 for (Option o : Option.values()) {
233 los.add(new LongOpt(o.getName(), o.requiresArgument() ? LongOpt.REQUIRED_ARGUMENT : LongOpt.NO_ARGUMENT, null, 0));
234 }
235
236 Getopt g = new Getopt("JOSM", args, "hv", los.toArray(new LongOpt[los.size()]));
237
238 Map<Option, Collection<String>> argMap = new HashMap<>();
239
240 int c;
241 while ((c = g.getopt()) != -1 ) {
242 Option opt = null;
243 switch (c) {
244 case 'h':
245 opt = Option.HELP;
246 break;
247 case 'v':
248 opt = Option.VERSION;
249 break;
250 case 0:
251 opt = Option.values()[g.getLongind()];
252 break;
253 }
254 if (opt != null) {
255 Collection<String> values = argMap.get(opt);
256 if (values == null) {
257 values = new ArrayList<>();
258 argMap.put(opt, values);
259 }
260 values.add(g.getOptarg());
261 } else
262 throw new IllegalArgumentException();
263 }
264 // positional arguments are a shortcut for the --download ... option
265 for (int i = g.getOptind(); i < args.length; ++i) {
266 Collection<String> values = argMap.get(Option.DOWNLOAD);
267 if (values == null) {
268 values = new ArrayList<>();
269 argMap.put(Option.DOWNLOAD, values);
270 }
271 values.add(args[i]);
272 }
273
274 return argMap;
275 }
276
277 /**
278 * Main application Startup
279 * @param argArray Command-line arguments
280 */
281 public static void main(final String[] argArray) {
282 I18n.init();
283 Main.checkJavaVersion();
284
285 // construct argument table
286 Map<Option, Collection<String>> args = null;
287 try {
288 args = buildCommandLineArgumentMap(argArray);
289 } catch (IllegalArgumentException e) {
290 System.exit(1);
291 return;
292 }
293
294 final boolean languageGiven = args.containsKey(Option.LANGUAGE);
295
296 if (languageGiven) {
297 I18n.set(args.get(Option.LANGUAGE).iterator().next());
298 }
299
300 initApplicationPreferences();
301
302 Policy.setPolicy(new Policy() {
303 // Permissions for plug-ins loaded when josm is started via webstart
304 private PermissionCollection pc;
305
306 {
307 pc = new Permissions();
308 pc.add(new AllPermission());
309 }
310
311 @Override
312 public void refresh() { }
313
314 @Override
315 public PermissionCollection getPermissions(CodeSource codesource) {
316 return pc;
317 }
318 });
319
320 Thread.setDefaultUncaughtExceptionHandler(new BugReportExceptionHandler());
321
322 // initialize the platform hook, and
323 Main.determinePlatformHook();
324 // call the really early hook before we do anything else
325 Main.platform.preStartupHook();
326
327 Main.commandLineArgs = Utils.copyArray(argArray);
328
329 if (args.containsKey(Option.VERSION)) {
330 System.out.println(Version.getInstance().getAgentString());
331 System.exit(0);
332 }
333
334 if (args.containsKey(Option.DEBUG) || args.containsKey(Option.TRACE)) {
335 // Enable JOSM debug level
336 logLevel = 4;
337 Main.info(tr("Printing debugging messages to console"));
338 }
339
340 if (args.containsKey(Option.TRACE)) {
341 // Enable JOSM debug level
342 logLevel = 5;
343 // Enable debug in OAuth signpost via system preference, but only at trace level
344 Preferences.updateSystemProperty("debug", "true");
345 Main.info(tr("Enabled detailed debug level (trace)"));
346 }
347
348 Main.pref.init(args.containsKey(Option.RESET_PREFERENCES));
349
350 if (!languageGiven) {
351 I18n.set(Main.pref.get("language", null));
352 }
353 Main.pref.updateSystemProperties();
354
355 // asking for help? show help and exit
356 if (args.containsKey(Option.HELP)) {
357 showHelp();
358 System.exit(0);
359 }
360
361 processOffline(args);
362
363 FontsManager.initialize();
364
365 final JFrame mainFrame = new JFrame(tr("Java OpenStreetMap Editor"));
366 Main.parent = mainFrame;
367
368 if (args.containsKey(Option.LOAD_PREFERENCES)) {
369 CustomConfigurator.XMLCommandProcessor config = new CustomConfigurator.XMLCommandProcessor(Main.pref);
370 for (String i : args.get(Option.LOAD_PREFERENCES)) {
371 info("Reading preferences from " + i);
372 try (InputStream is = Utils.openURL(new URL(i))) {
373 config.openAndReadXML(is);
374 } catch (Exception ex) {
375 throw new RuntimeException(ex);
376 }
377 }
378 }
379
380 if (args.containsKey(Option.SET)) {
381 for (String i : args.get(Option.SET)) {
382 String[] kv = i.split("=", 2);
383 Main.pref.put(kv[0], "null".equals(kv[1]) ? null : kv[1]);
384 }
385 }
386
387 DefaultAuthenticator.createInstance();
388 Authenticator.setDefault(DefaultAuthenticator.getInstance());
389 DefaultProxySelector proxySelector = new DefaultProxySelector(ProxySelector.getDefault());
390 ProxySelector.setDefault(proxySelector);
391 OAuthAccessTokenHolder.getInstance().init(Main.pref, CredentialsManager.getInstance());
392
393 final SplashScreen splash = new SplashScreen();
394 final ProgressMonitor monitor = splash.getProgressMonitor();
395 monitor.beginTask(tr("Initializing"));
396 splash.setVisible(Main.pref.getBoolean("draw.splashscreen", true));
397 Main.setInitStatusListener(new InitStatusListener() {
398
399 @Override
400 public void updateStatus(String event) {
401 monitor.indeterminateSubTask(event);
402 }
403 });
404
405 Collection<PluginInformation> pluginsToLoad = PluginHandler.buildListOfPluginsToLoad(splash,monitor.createSubTaskMonitor(1, false));
406 if (!pluginsToLoad.isEmpty() && PluginHandler.checkAndConfirmPluginUpdate(splash)) {
407 monitor.subTask(tr("Updating plugins"));
408 pluginsToLoad = PluginHandler.updatePlugins(splash, null, monitor.createSubTaskMonitor(1, false), false);
409 }
410
411 monitor.indeterminateSubTask(tr("Installing updated plugins"));
412 PluginHandler.installDownloadedPlugins(true);
413
414 monitor.indeterminateSubTask(tr("Loading early plugins"));
415 PluginHandler.loadEarlyPlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
416
417 monitor.indeterminateSubTask(tr("Setting defaults"));
418 preConstructorInit(args);
419
420 monitor.indeterminateSubTask(tr("Creating main GUI"));
421 final Main main = new MainApplication(mainFrame);
422
423 monitor.indeterminateSubTask(tr("Loading plugins"));
424 PluginHandler.loadLatePlugins(splash,pluginsToLoad, monitor.createSubTaskMonitor(1, false));
425 toolbar.refreshToolbarControl();
426
427 // Wait for splash disappearance (fix #9714)
428 GuiHelper.runInEDTAndWait(new Runnable() {
429 @Override
430 public void run() {
431 splash.setVisible(false);
432 splash.dispose();
433 mainFrame.setVisible(true);
434 }
435 });
436
437 Main.MasterWindowListener.setup();
438
439 boolean maximized = Main.pref.getBoolean("gui.maximized", false);
440 if ((!args.containsKey(Option.NO_MAXIMIZE) && maximized) || args.containsKey(Option.MAXIMIZE)) {
441 if (Toolkit.getDefaultToolkit().isFrameStateSupported(JFrame.MAXIMIZED_BOTH)) {
442 Main.windowState = JFrame.MAXIMIZED_BOTH;
443 mainFrame.setExtendedState(Main.windowState);
444 } else {
445 Main.debug("Main window: maximizing not supported");
446 }
447 }
448 if (main.menu.fullscreenToggleAction != null) {
449 main.menu.fullscreenToggleAction.initial();
450 }
451
452 SwingUtilities.invokeLater(new GuiFinalizationWorker(args, proxySelector));
453
454 if (Main.isPlatformWindows()) {
455 try {
456 // Check for insecure certificates to remove.
457 // This is Windows-dependant code but it can't go to preStartupHook (need i18n) neither startupHook (need to be called before remote control)
458 PlatformHookWindows.removeInsecureCertificates();
459 } catch (NoSuchAlgorithmException | CertificateException | KeyStoreException | IOException e) {
460 error(e);
461 }
462 }
463
464 if (RemoteControl.PROP_REMOTECONTROL_ENABLED.get()) {
465 RemoteControl.start();
466 }
467
468 if (MessageNotifier.PROP_NOTIFIER_ENABLED.get()) {
469 MessageNotifier.start();
470 }
471
472 if (Main.pref.getBoolean("debug.edt-checker.enable", Version.getInstance().isLocalBuild())) {
473 // 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
474 info("Enabled EDT checker, wrongful access to gui from non EDT thread will be printed to console");
475 RepaintManager.setCurrentManager(new CheckThreadViolationRepaintManager());
476 }
477 }
478
479 private static void processOffline(Map<Option, Collection<String>> args) {
480 if (args.containsKey(Option.OFFLINE)) {
481 for (String s : args.get(Option.OFFLINE).iterator().next().split(",")) {
482 try {
483 Main.setOffline(OnlineResource.valueOf(s.toUpperCase()));
484 } catch (IllegalArgumentException e) {
485 Main.error(tr("''{0}'' is not a valid value for argument ''{1}''. Possible values are {2}, possibly delimited by commas.",
486 s.toUpperCase(), Option.OFFLINE.getName(), Arrays.toString(OnlineResource.values())));
487 System.exit(1);
488 return;
489 }
490 }
491 Set<OnlineResource> offline = Main.getOfflineResources();
492 if (!offline.isEmpty()) {
493 Main.warn(trn("JOSM is running in offline mode. This resource will not be available: {0}",
494 "JOSM is running in offline mode. These resources will not be available: {0}",
495 offline.size(), offline.size() == 1 ? offline.iterator().next() : Arrays.toString(offline.toArray())));
496 }
497 }
498 }
499
500 private static class GuiFinalizationWorker implements Runnable {
501
502 private final Map<Option, Collection<String>> args;
503 private final DefaultProxySelector proxySelector;
504
505 public GuiFinalizationWorker(Map<Option, Collection<String>> args, DefaultProxySelector proxySelector) {
506 this.args = args;
507 this.proxySelector = proxySelector;
508 }
509
510 @Override
511 public void run() {
512
513 // Handle proxy/network errors early to inform user he should change settings to be able to use JOSM correctly
514 if (!handleProxyErrors()) {
515 handleNetworkErrors();
516 }
517
518 // Restore autosave layers after crash and start autosave thread
519 handleAutosave();
520
521 // Handle command line instructions
522 postConstructorProcessCmdLine(args);
523
524 // Show download dialog if autostart is enabled
525 DownloadDialog.autostartIfNeeded();
526 }
527
528 private void handleAutosave() {
529 if (AutosaveTask.PROP_AUTOSAVE_ENABLED.get()) {
530 AutosaveTask autosaveTask = new AutosaveTask();
531 List<File> unsavedLayerFiles = autosaveTask.getUnsavedLayersFiles();
532 if (!unsavedLayerFiles.isEmpty()) {
533 ExtendedDialog dialog = new ExtendedDialog(
534 Main.parent,
535 tr("Unsaved osm data"),
536 new String[] {tr("Restore"), tr("Cancel"), tr("Discard")}
537 );
538 dialog.setContent(
539 trn("JOSM found {0} unsaved osm data layer. ",
540 "JOSM found {0} unsaved osm data layers. ", unsavedLayerFiles.size(), unsavedLayerFiles.size()) +
541 tr("It looks like JOSM crashed last time. Would you like to restore the data?"));
542 dialog.setButtonIcons(new String[] {"ok", "cancel", "dialogs/delete"});
543 int selection = dialog.showDialog().getValue();
544 if (selection == 1) {
545 autosaveTask.recoverUnsavedLayers();
546 } else if (selection == 3) {
547 autosaveTask.discardUnsavedLayers();
548 }
549 }
550 autosaveTask.schedule();
551 }
552 }
553
554 private boolean handleNetworkOrProxyErrors(boolean hasErrors, String title, String message) {
555 if (hasErrors) {
556 ExtendedDialog ed = new ExtendedDialog(
557 Main.parent, title,
558 new String[]{tr("Change proxy settings"), tr("Cancel")});
559 ed.setButtonIcons(new String[]{"dialogs/settings.png", "cancel.png"}).setCancelButton(2);
560 ed.setMinimumSize(new Dimension(460, 260));
561 ed.setIcon(JOptionPane.WARNING_MESSAGE);
562 ed.setContent(message);
563
564 if (ed.showDialog().getValue() == 1) {
565 PreferencesAction.forPreferenceSubTab(null, null, ProxyPreference.class).run();
566 }
567 }
568 return hasErrors;
569 }
570
571 private boolean handleProxyErrors() {
572 return handleNetworkOrProxyErrors(proxySelector.hasErrors(), tr("Proxy errors occurred"),
573 tr("JOSM tried to access the following resources:<br>" +
574 "{0}" +
575 "but <b>failed</b> to do so, because of the following proxy errors:<br>" +
576 "{1}" +
577 "Would you like to change your proxy settings now?",
578 Utils.joinAsHtmlUnorderedList(proxySelector.getErrorResources()),
579 Utils.joinAsHtmlUnorderedList(proxySelector.getErrorMessages())
580 ));
581 }
582
583 private boolean handleNetworkErrors() {
584 boolean condition = !NETWORK_ERRORS.isEmpty();
585 if (condition) {
586 Set<String> errors = new TreeSet<>();
587 for (Throwable t : NETWORK_ERRORS.values()) {
588 errors.add(t.toString());
589 }
590 return handleNetworkOrProxyErrors(condition, tr("Network errors occurred"),
591 tr("JOSM tried to access the following resources:<br>" +
592 "{0}" +
593 "but <b>failed</b> to do so, because of the following network errors:<br>" +
594 "{1}" +
595 "It may be due to a missing proxy configuration.<br>" +
596 "Would you like to change your proxy settings now?",
597 Utils.joinAsHtmlUnorderedList(NETWORK_ERRORS.keySet()),
598 Utils.joinAsHtmlUnorderedList(errors)
599 ));
600 }
601 return false;
602 }
603 }
604}
Note: See TracBrowser for help on using the repository browser.