package com.revolsys.swing.parallel; import java.awt.Image; import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.Method; import java.util.Enumeration; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.ToolTipManager; import javax.swing.UIManager; import javax.swing.UIManager.LookAndFeelInfo; import org.apache.commons.beanutils.MethodUtils; import org.apache.log4j.Appender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.spi.LoggingEvent; import com.revolsys.logging.Logs; import com.revolsys.swing.listener.MacApplicationListenerHandler; import com.revolsys.swing.logging.ListLog4jAppender; import com.revolsys.swing.logging.LoggingEventPanel; import com.revolsys.util.Property; public class BaseMain implements UncaughtExceptionHandler { public static void run(final Class<? extends BaseMain> mainClass, final String[] args) { try { final BaseMain main = mainClass.newInstance(); main.processArguments(args); main.run(); } catch (final Throwable e) { Logs.error(mainClass, e); } } protected static void setMacDockIcon(final Image image) { try { final Class<?> clazz = Class.forName("com.apple.eawt.Application"); final Method appMethod = clazz.getMethod("getApplication"); final Object application = appMethod.invoke(clazz); if (image != null) { MethodUtils.invokeMethod(application, "setDockIconImage", image); } final Class<?> quitStrategyClass = Class.forName("com.apple.eawt.QuitStrategy"); final Object closeAllWindows = quitStrategyClass.getField("CLOSE_ALL_WINDOWS") .get(quitStrategyClass); MethodUtils.invokeExactMethod(application, "setQuitStrategy", closeAllWindows); MacApplicationListenerHandler.init(application); } catch (final ClassNotFoundException t) { } catch (final Throwable t) { t.printStackTrace(); } } private String lookAndFeelName; private final String name; public BaseMain(final String name) { this.name = name; Thread.setDefaultUncaughtExceptionHandler(this); } public String getLookAndFeelName() { return this.lookAndFeelName; } public void logError(final Throwable e) { final Logger logger = Logger.getLogger(getClass()); final LoggingEvent event = new LoggingEvent(logger.getClass().getName(), logger, Level.ERROR, "Unable to start application", e); LoggingEventPanel.showDialog(null, event); Logs.error(this, "Unable to start application " + this.name, e); } protected void preRunDo() throws Throwable { } public void processArguments(final String[] args) { } public void run() { try { preRunDo(); Invoke.later(() -> { try { runDo(); } catch (final Throwable e) { logError(e); } }); } catch (final Throwable e) { logError(e); } } protected void runDo() throws Throwable { boolean lookSet = false; if (Property.hasValue(this.lookAndFeelName)) { final LookAndFeelInfo[] installedLookAndFeels = UIManager.getInstalledLookAndFeels(); for (final LookAndFeelInfo lookAndFeelInfo : installedLookAndFeels) { final String name = lookAndFeelInfo.getName(); if (this.lookAndFeelName.equals(name)) { try { final String className = lookAndFeelInfo.getClassName(); UIManager.setLookAndFeel(className); lookSet = true; } catch (final Throwable e) { } } } } if (!lookSet) { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } JFrame.setDefaultLookAndFeelDecorated(true); JDialog.setDefaultLookAndFeelDecorated(true); ToolTipManager.sharedInstance().setInitialDelay(100); } public void setLookAndFeelName(final String lookAndFeelName) { this.lookAndFeelName = lookAndFeelName; } @Override public void uncaughtException(final Thread t, final Throwable e) { final Class<? extends BaseMain> logClass = getClass(); String message = e.getMessage(); if (!Property.hasValue(message)) { if (e instanceof NullPointerException) { message = "Null pointer"; } else { message = "Unknown error"; } } Logs.error(logClass, message, e); @SuppressWarnings("unchecked") final Enumeration<Appender> allAppenders = Logger.getRootLogger().getAllAppenders(); while (allAppenders.hasMoreElements()) { final Appender appender = allAppenders.nextElement(); if (appender instanceof ListLog4jAppender) { return; } } final Logger logger = Logger.getLogger(logClass); final LoggingEvent event = new LoggingEvent(logger.getClass().getName(), logger, Level.ERROR, message, e); LoggingEventPanel.showDialog(null, event); } }