PageRenderTime 56ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/limewire/private-components/integrated-ui/src/main/java/org/limewire/ui/swing/Initializer.java

https://github.com/WIZARDISHUNGRY/limewire
Java | 634 lines | 407 code | 88 blank | 139 comment | 38 complexity | a0207fad2a08091b4c21cf2a83eaa665 MD5 | raw file
  1. package org.limewire.ui.swing;
  2. import java.awt.Frame;
  3. import java.awt.Image;
  4. import java.io.File;
  5. import java.io.FileInputStream;
  6. import java.io.FileOutputStream;
  7. import java.io.IOException;
  8. import java.lang.reflect.InvocationTargetException;
  9. import java.util.List;
  10. import java.util.Locale;
  11. import java.util.Properties;
  12. import java.util.concurrent.atomic.AtomicReference;
  13. import javax.swing.JLabel;
  14. import javax.swing.JOptionPane;
  15. import javax.swing.SwingUtilities;
  16. import javax.swing.UIManager;
  17. import javax.swing.plaf.basic.BasicHTML;
  18. import org.apache.commons.logging.Log;
  19. import org.apache.commons.logging.LogFactory;
  20. import org.jdesktop.application.Application;
  21. import org.limewire.core.impl.mozilla.LimeMozillaOverrides;
  22. import org.limewire.core.settings.ConnectionSettings;
  23. import org.limewire.io.IOUtils;
  24. import org.limewire.service.ErrorService;
  25. import org.limewire.service.MessageService;
  26. import org.limewire.ui.support.BugManager;
  27. import org.limewire.ui.support.DeadlockSupport;
  28. import org.limewire.ui.support.ErrorHandler;
  29. import org.limewire.ui.support.FatalBugManager;
  30. import org.limewire.ui.swing.browser.LimeMozillaInitializer;
  31. import org.limewire.ui.swing.components.MultiLineLabel;
  32. import org.limewire.ui.swing.components.SplashWindow;
  33. import org.limewire.ui.swing.event.ExceptionPublishingSwingEventService;
  34. import org.limewire.ui.swing.mainframe.AppFrame;
  35. import org.limewire.ui.swing.settings.StartupSettings;
  36. import org.limewire.ui.swing.util.I18n;
  37. import org.limewire.ui.swing.util.LocaleUtils;
  38. import org.limewire.ui.swing.util.MacOSXUtils;
  39. import org.limewire.ui.swing.util.SwingUtils;
  40. import org.limewire.ui.swing.wizard.IntentDialog;
  41. import org.limewire.util.CommonUtils;
  42. import org.limewire.util.I18NConvert;
  43. import org.limewire.util.OSUtils;
  44. import org.limewire.util.Stopwatch;
  45. import org.limewire.util.SystemUtils;
  46. import org.mozilla.browser.MozillaPanel;
  47. import com.google.inject.AbstractModule;
  48. import com.google.inject.Guice;
  49. import com.google.inject.Injector;
  50. import com.google.inject.Stage;
  51. import com.limegroup.gnutella.ActiveLimeWireCheck;
  52. import com.limegroup.gnutella.LimeCoreGlue;
  53. import com.limegroup.gnutella.LimeWireCore;
  54. import com.limegroup.gnutella.LimeCoreGlue.InstallFailedException;
  55. import com.limegroup.gnutella.browser.ExternalControl;
  56. import com.limegroup.gnutella.util.LimeWireUtils;
  57. import com.limegroup.gnutella.util.LogUtils;
  58. /** Initializes (creates, starts, & displays) the LimeWire Core & UI. */
  59. public final class Initializer {
  60. /** The log -- set only after Log4J can be determined. */
  61. private final Log LOG;
  62. /** Refuse to start after this date */
  63. private final long EXPIRATION_DATE = Long.MAX_VALUE;
  64. /** True if is running from a system startup. */
  65. private volatile boolean isStartup = false;
  66. /** The start memory -- only set if debugging. */
  67. private long startMemory;
  68. /** A stopwatch for debug logging. */
  69. private final Stopwatch stopwatch;
  70. /** The SplashWindow reference. */
  71. private final AtomicReference<SplashWindow> splashRef = new AtomicReference<SplashWindow>();
  72. Initializer() {
  73. // If Log4J is available then remove the NoOpLog
  74. if (LogUtils.isLog4JAvailable()) {
  75. System.getProperties().remove("org.apache.commons.logging.Log");
  76. }
  77. LOG = LogFactory.getLog(Initializer.class);
  78. if(LOG.isTraceEnabled()) {
  79. startMemory = Runtime.getRuntime().totalMemory()
  80. - Runtime.getRuntime().freeMemory();
  81. LOG.trace("START Initializer, using: " + startMemory + " memory");
  82. }
  83. stopwatch = new Stopwatch(LOG);
  84. }
  85. /**
  86. * Initializes all of the necessary application classes.
  87. *
  88. * If this throws any exceptions, then LimeWire was not able to construct
  89. * properly and must be shut down.
  90. */
  91. void initialize(String args[], Frame awtSplash, Image splashImage) throws Throwable {
  92. // ** THE VERY BEGINNING -- DO NOT ADD THINGS BEFORE THIS **
  93. preinit();
  94. // Various startup tasks...
  95. setupCallbacksAndListeners();
  96. validateStartup(args);
  97. // Creates LimeWire itself.
  98. LimeWireCore limeWireCore = createLimeWire();
  99. Injector injector = limeWireCore.getInjector();
  100. // Various tasks that can be done after core is glued & started.
  101. glueCore(limeWireCore);
  102. validateEarlyCore(limeWireCore);
  103. // Validate any arguments or properties outside of the LW environment.
  104. runExternalChecks(limeWireCore, args, injector);
  105. // Starts some system monitoring for deadlocks.
  106. DeadlockSupport.startDeadlockMonitoring();
  107. stopwatch.resetAndLog("Start deadlock monitor");
  108. // Installs properties.
  109. installProperties();
  110. // show nifty alpha info
  111. // showAlphaInfo();
  112. //must agree not to use LW for copyright infringement on first running
  113. confirmIntent(awtSplash);
  114. boolean isPro = injector.getInstance(org.limewire.core.api.Application.class).isProVersion();
  115. // Move from the AWT splash to the Swing splash & start early core.
  116. //assuming not showing splash screen if there are program arguments
  117. switchSplashes(awtSplash, splashImage, isPro);
  118. startEarlyCore(limeWireCore);
  119. // Initialize early UI components, display the setup manager (if necessary),
  120. // and ensure the save directory is valid.
  121. initializeEarlyUI(injector.getInstance(LimeMozillaOverrides.class));
  122. // Load the UI, system tray & notification handlers,
  123. // and hide the splash screen & display the UI.
  124. loadUI();
  125. enablePreferences();
  126. SettingsWarningManager.checkTemporaryDirectoryUsage();
  127. SettingsWarningManager.checkSettingsLoadSaveFailure();
  128. // Start the core & run any queued control requests, and load DAAP.
  129. startCore(limeWireCore);
  130. runQueuedRequests(limeWireCore);
  131. // Run any after-init tasks.
  132. postinit();
  133. }
  134. // private void showAlphaInfo() {
  135. // final String msg = "Welcome to the LimeWire 5 Alpha!\n\n"
  136. // + "Here's some important information about the alpha...\n"
  137. // + " - There are bugs. Lots. It's because this is an alpha.\n"
  138. // + " We're confident the program is stable (it's not going\n"
  139. // + " to delete your computer or anything), but you will run\n"
  140. // + " into some internal errors.\n"
  141. // + " - It isn't finished. We're very actively working on\n"
  142. // + " changes, tweaks, rewrites, and all sorts of things.\n"
  143. // + " - Everything can (and probably will) change. Don't\n"
  144. // + " take inclusion or exclusion of a certain feature to\n"
  145. // + " mean that we're adding or dropping it. It's probably\n"
  146. // + " just an oversight.\n\n"
  147. // + " Thanks!\n"
  148. // + " The LimeWire Team";
  149. // SwingUtils.invokeAndWait(new Runnable() {
  150. // public void run() {
  151. // JOptionPane.showMessageDialog(null,
  152. // msg,
  153. // "LimeWire 5 Alpha Info",
  154. // JOptionPane.INFORMATION_MESSAGE);
  155. // }
  156. // });
  157. // }
  158. /**
  159. * Shows legal conditions and exits if the user does not agree to them.
  160. *
  161. * Takes a parameter for the splash screen so it can hide it if
  162. * the intent dialogue needs to be shown to avoid a troublesome situation
  163. * where the splash screen actually covers the shown intent dialogue.
  164. */
  165. private void confirmIntent(final Frame awtSplash) {
  166. File versionFile = new File(CommonUtils.getUserSettingsDir(), "versions.props");
  167. Properties properties = new Properties();
  168. FileInputStream inputStream = null;
  169. try {
  170. inputStream = new FileInputStream(versionFile);
  171. properties.load(inputStream);
  172. } catch (IOException iox) {
  173. } finally {
  174. IOUtils.close(inputStream);
  175. }
  176. String exists = properties.getProperty(LimeWireUtils.getLimeWireVersion());
  177. if (exists == null || !exists.equals("true")) {
  178. SwingUtils.invokeAndWait(new Runnable() {
  179. @Override
  180. public void run() {
  181. if (awtSplash != null) {
  182. awtSplash.setVisible(false);
  183. }
  184. boolean confirmed = new IntentDialog(LimeWireUtils.getLimeWireVersion()).confirmLegal();
  185. if (!confirmed) {
  186. System.exit(0);
  187. }
  188. if (awtSplash != null) {
  189. awtSplash.setVisible(true);
  190. }
  191. }
  192. });
  193. properties.put(LimeWireUtils.getLimeWireVersion(), "true");
  194. FileOutputStream outputStream = null;
  195. try {
  196. outputStream = new FileOutputStream(versionFile);
  197. properties.store(outputStream, "Started & Ran Versions");
  198. } catch (IOException ignored) {
  199. } finally {
  200. IOUtils.close(outputStream);
  201. }
  202. }
  203. }
  204. /** Initializes the very early things. */
  205. /*
  206. * DO NOT CHANGE THIS WITHOUT KNOWING WHAT YOU'RE DOING.
  207. * PREINSTALL MUST BE DONE BEFORE ANYTHING ELSE IS REFERENCED.
  208. * (Because it sets the preference directory in CommonUtils.)
  209. */
  210. private void preinit() {
  211. // Make sure the settings directory is set.
  212. try {
  213. LimeCoreGlue.preinstall();
  214. stopwatch.resetAndLog("Preinstall");
  215. } catch(InstallFailedException ife) {
  216. failPreferencesPermissions();
  217. }
  218. // Before anything, set a default L&F, so that
  219. // if an error occurs, we can display the error
  220. // message with the right L&F.
  221. SwingUtils.invokeLater(new Runnable() {
  222. public void run() {
  223. String name = UIManager.getSystemLookAndFeelClassName();
  224. if(OSUtils.isLinux()) {
  225. //mozswing on linux is not compatible with the gtklook and feel in jvms less than 1.7
  226. //forcing cross platform look and feel for linux.
  227. name = UIManager.getCrossPlatformLookAndFeelClassName();
  228. }
  229. try {
  230. UIManager.setLookAndFeel(name);
  231. } catch(Throwable ignored) {}
  232. }
  233. });
  234. }
  235. /** Installs all callbacks & listeners. */
  236. private void setupCallbacksAndListeners() {
  237. SwingUtils.invokeAndWait(new Runnable() {
  238. @Override
  239. public void run() {
  240. BugManager.instance();
  241. }
  242. });
  243. // Set the error handler so we can receive core errors.
  244. ErrorService.setErrorCallback(new ErrorHandler());
  245. // set error handler for uncaught exceptions originating from non-LW
  246. Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandlerImpl());
  247. stopwatch.resetAndLog("ErrorHandler install");
  248. // Set the messaging handler so we can receive core messages
  249. MessageService.setCallback(new MessageHandler());
  250. stopwatch.resetAndLog("MessageHandler install");
  251. // Set the default event error handler so we can receive uncaught
  252. // AWT errors.
  253. DefaultErrorCatcher.install();
  254. stopwatch.resetAndLog("DefaultErrorCatcher install");
  255. //Enable the EDT event service (used by the EventBus library) that publishes to LW error handling
  256. ExceptionPublishingSwingEventService.install();
  257. stopwatch.resetAndLog("DefaultErrorCatcher install");
  258. if (OSUtils.isMacOSX()) {
  259. // Raise the number of allowed concurrent open files to 1024.
  260. SystemUtils.setOpenFileLimit(1024);
  261. stopwatch.resetAndLog("Open file limit raise");
  262. MacEventHandler.instance();
  263. stopwatch.resetAndLog("MacEventHandler instance");
  264. }
  265. }
  266. /**
  267. * Ensures this should continue running, by checking
  268. * for expiration failures or startup settings.
  269. */
  270. private void validateStartup(String[] args) {
  271. // check if this version has expired.
  272. if (System.currentTimeMillis() > EXPIRATION_DATE)
  273. failExpired();
  274. // Yield so any other events can be run to determine
  275. // startup status, but only if we're going to possibly
  276. // be starting...
  277. if(StartupSettings.RUN_ON_STARTUP.getValue()) {
  278. stopwatch.reset();
  279. Thread.yield();
  280. stopwatch.resetAndLog("Thread yield");
  281. }
  282. if (args.length >= 1 && "-startup".equals(args[0]))
  283. isStartup = true;
  284. if (isStartup) {
  285. args = null; // reset for later Active check
  286. // if the user doesn't want to start on system startup, exit the
  287. // JVM immediately
  288. if(!StartupSettings.RUN_ON_STARTUP.getValue())
  289. System.exit(0);
  290. }
  291. // Exit if another LimeWire is already running...
  292. ActiveLimeWireCheck activeLimeWireCheck = new ActiveLimeWireCheck(args, StartupSettings.ALLOW_MULTIPLE_INSTANCES.getValue());
  293. stopwatch.resetAndLog("Create ActiveLimeWireCheck");
  294. if (activeLimeWireCheck.checkForActiveLimeWire()) {
  295. System.exit(0);
  296. }
  297. stopwatch.resetAndLog("Run ActiveLimeWireCheck");
  298. }
  299. /** Wires together LimeWire. */
  300. private LimeWireCore createLimeWire() {
  301. stopwatch.reset();
  302. Injector injector = Guice.createInjector(Stage.PRODUCTION, new LimeWireModule(), new AbstractModule() {
  303. @Override
  304. protected void configure() {
  305. requestStaticInjection(AppFrame.class);
  306. }
  307. });
  308. stopwatch.resetAndLog("Create injector");
  309. return injector.getInstance(LimeWireCore.class);
  310. }
  311. /** Wires together remaining non-Guiced pieces. */
  312. private void glueCore(LimeWireCore limeWireCore) {
  313. limeWireCore.getLimeCoreGlue().install();
  314. stopwatch.resetAndLog("Install core glue");
  315. }
  316. /** Tasks that can be done after core is created, before it's started. */
  317. private void validateEarlyCore(LimeWireCore limeWireCore) {
  318. // See if our NIODispatcher clunked out.
  319. if(!limeWireCore.getNIODispatcher().isRunning()) {
  320. failInternetBlocked();
  321. }
  322. stopwatch.resetAndLog("Check for NIO dispatcher");
  323. }
  324. /**
  325. * Initializes any code that is dependent on external controls.
  326. * Specifically, GURLHandler & MacEventHandler on OS X,
  327. * ensuring that multiple LimeWire's can't run at once,
  328. * and processing any arguments that were passed to LimeWire.
  329. */
  330. private void runExternalChecks(LimeWireCore limeWireCore, String[] args, Injector injector) {
  331. ExternalControl externalControl = limeWireCore.getExternalControl();
  332. stopwatch.resetAndLog("Get externalControl");
  333. if(OSUtils.isMacOSX()) {
  334. GURLHandler.getInstance().enable(externalControl);
  335. stopwatch.resetAndLog("Enable GURL");
  336. injector.injectMembers(MacEventHandler.instance());
  337. stopwatch.resetAndLog("Enable macEventHandler");
  338. }
  339. // Test for preexisting LimeWire and pass it a magnet URL if one
  340. // has been passed in.
  341. if (args.length > 0 && !args[0].equals("-startup")) {
  342. String arg = ExternalControl.preprocessArgs(args);
  343. stopwatch.resetAndLog("Preprocess args");
  344. externalControl.enqueueControlRequest(arg);
  345. stopwatch.resetAndLog("Enqueue control req");
  346. }
  347. }
  348. /** Installs any system properties. */
  349. private void installProperties() {
  350. System.setProperty("http.agent", LimeWireUtils.getHttpServer());
  351. stopwatch.resetAndLog("set system properties");
  352. if (OSUtils.isMacOSX()) {
  353. System.setProperty("user.fullname", MacOSXUtils.getUserName()); // for DAAP
  354. System.setProperty("apple.laf.useScreenMenuBar", "true");
  355. stopwatch.resetAndLog("set OSX properties");
  356. }
  357. SwingUtils.invokeAndWait(new Runnable() {
  358. public void run() {
  359. LocaleUtils.setLocaleFromPreferences();
  360. LocaleUtils.validateLocaleAndFonts();
  361. }
  362. });
  363. stopwatch.resetAndLog("set locale");
  364. }
  365. /** Starts any early core-related functionality. */
  366. private void startEarlyCore(LimeWireCore limeWireCore) {
  367. // Add this running program to the Windows Firewall Exceptions list
  368. boolean inFirewallException = limeWireCore.getFirewallService().addToFirewall();
  369. stopwatch.resetAndLog("add firewall exception");
  370. if(!inFirewallException) {
  371. limeWireCore.getLifecycleManager().loadBackgroundTasks();
  372. stopwatch.resetAndLog("load background tasks");
  373. }
  374. }
  375. /** Switches from the AWT splash to the Swing splash. */
  376. private void switchSplashes(final Frame awtSplash, final Image splashImage, final boolean isPro) {
  377. SwingUtils.invokeAndWait(new Runnable() {
  378. @Override
  379. public void run() {
  380. splashRef.set(new SplashWindow(splashImage, isPro, LocaleUtils.getCurrentLocale(), 4));
  381. if(!isStartup) {
  382. splashRef.get().begin();
  383. stopwatch.resetAndLog("begin splash window");
  384. }
  385. }
  386. });
  387. if(awtSplash != null) {
  388. awtSplash.dispose();
  389. stopwatch.resetAndLog("dispose AWT splash");
  390. }
  391. }
  392. /** Initializes any early UI tasks, such as HTML loading & the Bug Manager.
  393. * @param mozillaOverrides
  394. * @param mozillaOverrides */
  395. private void initializeEarlyUI(LimeMozillaOverrides mozillaOverrides) {
  396. // Load up the HTML engine.
  397. splashRef.get().setStatusText(I18n.tr("Muddling Mint...")); //html engine
  398. stopwatch.resetAndLog("update splash for HTML engine");
  399. SwingUtils.invokeAndWait(new Runnable() {
  400. public void run() {
  401. stopwatch.resetAndLog("enter evt queue");
  402. JLabel label = new JLabel();
  403. // setting font and color to null to minimize generated css
  404. // script, which causes a parser exception under circumstances
  405. label.setFont(null);
  406. label.setForeground(null);
  407. BasicHTML.createHTMLView(label, "<html>.</html>");
  408. stopwatch.resetAndLog("create HTML view");
  409. }
  410. });
  411. stopwatch.resetAndLog("return from evt queue");
  412. splashRef.get().setStatusText(I18n.tr("Scouring NYC for Limes...")); //loading browser
  413. // Not pretty but Mozilla initialization errors should not crash the
  414. // program
  415. if (LimeMozillaInitializer.shouldInitialize()) {
  416. // See LWC-2860 for why we change Turkish -> English.
  417. // If MozSwing ever fixes this for us, we can remove this workaround.
  418. Locale locale = Locale.getDefault();
  419. if(locale.getLanguage().equals("tr")) {
  420. Locale.setDefault(Locale.ENGLISH);
  421. }
  422. try {
  423. LimeMozillaInitializer.initialize();
  424. mozillaOverrides.overrideMozillaDefaults();
  425. } catch (Exception e) {
  426. // If it failed, don't keep the wrong locale active.
  427. Locale.setDefault(locale);
  428. LOG.error("Mozilla initialization failed");
  429. }
  430. stopwatch.resetAndLog("Load XUL Library Path");
  431. SwingUtils.invokeAndWait(new Runnable() {
  432. public void run() {
  433. stopwatch.resetAndLog("enter evt queue");
  434. new MozillaPanel();
  435. stopwatch.resetAndLog("Load MozillaPanel");
  436. }
  437. });
  438. }
  439. stopwatch.resetAndLog("return from evt queue");
  440. }
  441. /** Loads the UI. */
  442. private void loadUI() {
  443. splashRef.get().setStatusText(I18n.tr("Squeezing Limes...")); //loading user interface
  444. stopwatch.resetAndLog("update splash for UI");
  445. DefaultErrorCatcher.storeCaughtBugs();
  446. String[] launchParams = isStartup ? new String[] { AppFrame.STARTUP } : new String[0];
  447. Application.launch(AppFrame.class, launchParams);
  448. // Initialize late tasks, like Icon initialization & install listeners.
  449. loadLateTasksForUI();
  450. SwingUtils.invokeAndWait(new Runnable() {
  451. public void run() {
  452. splashRef.get().dispose();
  453. splashRef.set(null);
  454. List<Throwable> caughtBugs = DefaultErrorCatcher.getAndResetStoredBugs();
  455. if(!AppFrame.isStarted()) {
  456. // Report the last bug that caused us to fail.
  457. assert caughtBugs.size() > 0;
  458. FatalBugManager.handleFatalBug(caughtBugs.get(caughtBugs.size()-1));
  459. } else {
  460. for(Throwable throwable : caughtBugs) {
  461. ErrorService.error(throwable, "Startup Error");
  462. }
  463. }
  464. }
  465. });
  466. }
  467. private void enablePreferences() {
  468. if (OSUtils.isMacOSX()) {
  469. MacEventHandler.instance().enablePreferences();
  470. }
  471. }
  472. /** Runs any late UI tasks, such as initializing Icons, I18n support. */
  473. private void loadLateTasksForUI() {
  474. // Touch the I18N stuff to ensure it loads properly.
  475. splashRef.get().setStatusText(I18n.tr("Prepping Mojitos...")); //other languages?
  476. I18NConvert.instance();
  477. stopwatch.resetAndLog("I18nConvert instance");
  478. }
  479. /** Starts the core. */
  480. private void startCore(LimeWireCore limeWireCore) {
  481. // Start the backend threads. Note that the GUI is not yet visible,
  482. // but it needs to be constructed at this point
  483. limeWireCore.getLifecycleManager().start();
  484. stopwatch.resetAndLog("lifecycle manager start");
  485. if (!ConnectionSettings.DISABLE_UPNP.getValue()) {
  486. limeWireCore.getUPnPManager().start();
  487. stopwatch.resetAndLog("start UPnPManager");
  488. }
  489. }
  490. /** Runs control requests that we queued early in initializing. */
  491. private void runQueuedRequests(LimeWireCore limeWireCore) {
  492. // Activate a download for magnet URL locally if one exists
  493. limeWireCore.getExternalControl().runQueuedControlRequest();
  494. stopwatch.resetAndLog("run queued control req");
  495. }
  496. /** Runs post initialization tasks. */
  497. private void postinit() {
  498. if(LOG.isTraceEnabled()) {
  499. long stopMemory = Runtime.getRuntime().totalMemory()
  500. - Runtime.getRuntime().freeMemory();
  501. LOG.trace("STOP Initializer, using: " + stopMemory +
  502. " memory, consumed: " + (stopMemory - startMemory));
  503. }
  504. }
  505. /**
  506. * Sets the startup property to be true.
  507. */
  508. void setStartup() {
  509. isStartup = true;
  510. }
  511. /** Fails because alpha expired. */
  512. private void failExpired() {
  513. fail(I18n.tr("This Alpha version has expired. Press Ok to exit. "));
  514. }
  515. /** Fails because internet is blocked. */
  516. private void failInternetBlocked() {
  517. fail(I18n
  518. .tr("LimeWire was unable to initialize and start. This is usually due to a firewall program blocking LimeWire\'s access to the internet or loopback connections on the local machine. Please allow LimeWire access to the internet and restart LimeWire."));
  519. }
  520. /** Fails because preferences can't be set. */
  521. private void failPreferencesPermissions() {
  522. fail(I18n.tr("LimeWire could not create a temporary preferences folder.\n\nThis is generally caused by a lack of permissions. Please make sure that LimeWire (and you) have access to create files/folders on your computer. If the problem persists, please visit www.limewire.com and click the \'Support\' link.\n\nLimeWire will now exit. Thank You."));
  523. }
  524. /** Shows a msg & fails. */
  525. private void fail(final String msgKey) {
  526. try {
  527. SwingUtilities.invokeAndWait(new Runnable() {
  528. public void run() {
  529. JOptionPane.showMessageDialog(null,
  530. new MultiLineLabel(msgKey, 300),
  531. "Error",
  532. JOptionPane.ERROR_MESSAGE);
  533. }
  534. });
  535. } catch (InterruptedException ignored) {
  536. } catch (InvocationTargetException e) {
  537. Throwable cause = e.getCause();
  538. if(cause instanceof RuntimeException)
  539. throw (RuntimeException)cause;
  540. if(cause instanceof Error)
  541. throw (Error)cause;
  542. throw new RuntimeException(cause);
  543. }
  544. System.exit(1);
  545. }
  546. }