PageRenderTime 65ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

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

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