From cbf24e0288e6004e3e9140d67603573afb16c24e Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Mon, 27 Jul 2015 15:21:16 +0200 Subject: [client] One step forward and two steps back... --- dozentenmodul/pom.xml | 194 +----------------- .../src/main/java/org/openslx/dozmod/App.java | 30 +-- .../src/main/java/org/openslx/dozmod/AwtBox.java | 81 -------- .../src/main/java/org/openslx/dozmod/gui/Gui.java | 224 +++++++++------------ .../org/openslx/dozmod/gui/helper/MessageType.java | 25 ++- 5 files changed, 126 insertions(+), 428 deletions(-) delete mode 100644 dozentenmodul/src/main/java/org/openslx/dozmod/AwtBox.java diff --git a/dozentenmodul/pom.xml b/dozentenmodul/pom.xml index fa88699e..e82bce9b 100644 --- a/dozentenmodul/pom.xml +++ b/dozentenmodul/pom.xml @@ -63,74 +63,25 @@ - true - org.apache.maven.plugins - maven-enforcer-plugin - 1.3.1 - - - enforce-maven-3 - - enforce - - - - - 3.0.0 - - - true - - - - - - org.apache.maven.plugins - maven-dependency-plugin - 2.10 + maven-assembly-plugin - copy - prepare-package + package - unpack + single - - META-INF/*.SF,META-INF/*.DSA,META-INF/*.RSA - ${project.build.outputDirectory} - true - - - com.janprach.multiplatform-swt - multiplatform-swt-loader - 4.4 - multiplatform - - - - - - org.springframework.boot - spring-boot-maven-plugin - 1.2.5.RELEASE - ${main.class} - - - org.eclipse.swt - ${swt.artifactId} - - + + + ${main.class} + + + + jar-with-dependencies + - - - - repackage - - - @@ -148,119 +99,8 @@ - - - - - org.eclipse.m2e - lifecycle-mapping - 1.0.0 - - - - - - - org.apache.maven.plugins - - - maven-dependency-plugin - - - [2.10,) - - - unpack - - - - - - - - - - - - - - - linux32 - - - linux - i386 - - - - org.eclipse.swt.gtk.linux.x86 - - - - linux64 - - - linux - amd64 - - - - org.eclipse.swt.gtk.linux.x86_64 - - - - macosx32 - - - macosx - i386 - - - - org.eclipse.swt.cocoa.macosx - - - - macosx64 - - - macosx - x86_64 - - - - org.eclipse.swt.cocoa.macosx.x86_64 - - - - win32 - - - windows - x86 - - - - org.eclipse.swt.win32.win32.x86 - - - - win64 - - - windows - amd64 - - - - org.eclipse.swt.win32.win32.x86_64 - - - - org.apache.thrift @@ -274,12 +114,6 @@ 2.4 compile - - org.eclipse.swt - ${swt.artifactId} - ${swt.version} - provided - log4j log4j @@ -320,12 +154,6 @@ joda-time 2.8 - - org.eclipse.jface - org.eclipse.jface - 3.8.0.v20120521-2329 - compile - diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/App.java b/dozentenmodul/src/main/java/org/openslx/dozmod/App.java index 6bd54d50..25213b0f 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/App.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/App.java @@ -2,13 +2,10 @@ package org.openslx.dozmod; import java.io.File; import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; import org.apache.log4j.AppenderSkeleton; import org.apache.log4j.BasicConfigurator; @@ -18,6 +15,7 @@ import org.apache.log4j.PatternLayout; import org.apache.log4j.spi.LoggingEvent; import org.openslx.dozmod.gui.Gui; import org.openslx.dozmod.gui.MainWindow; +import org.openslx.dozmod.gui.helper.MessageType; import org.openslx.dozmod.util.ProxyConfigurator; import org.openslx.thrifthelper.ThriftManager; @@ -99,7 +97,7 @@ public class App { try { Config.init(); } catch (Exception e) { - showAwtMessage("Error loading configuration", e); + Gui.showMessageBox("Error loading configuration", MessageType.ERROR, LOGGER, e); return; } @@ -113,15 +111,8 @@ public class App { } }; proxyThread.start(); - - // Check if we can load SWT by calling some library function - try { - Gui.display.getActiveShell(); - } catch (Throwable e) { - showAwtMessage("Error loading SWT libraries", e); - return; - } - // Setup swing + + // Setup swing style try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); } catch (Exception e1) { @@ -136,19 +127,6 @@ public class App { ThriftManager.setMasterServerAddress("bwlp-masterserver.ruf.uni-freiburg.de"); MainWindow.open(); - - // start the main window - Gui.mainloop(); - } - - private static void showAwtMessage(String message, Throwable e) { - LOGGER.error(message, e); - if (e != null) { - StringWriter sw = new StringWriter(); - e.printStackTrace(new PrintWriter(sw)); - message += "\n\n" + sw.toString(); - } - new AwtBox(null, message); } /** diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/AwtBox.java b/dozentenmodul/src/main/java/org/openslx/dozmod/AwtBox.java deleted file mode 100644 index 9ac9b87b..00000000 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/AwtBox.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.openslx.dozmod; - -import java.awt.BorderLayout; -import java.awt.Button; -import java.awt.Dialog; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Frame; -import java.awt.Panel; -import java.awt.TextArea; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - -/** - * Show a message box using AWT - used for when SWT fails. - */ -public class AwtBox extends Dialog implements ActionListener { - - private static final long serialVersionUID = 6254641637349233126L; - private Button okButton, cancelButton; - public boolean okClicked = false; - - /** - * @param frame parent frame - * @param message message to be displayed - * @param addCancelButton whether we want a cancel button too, instead of - * just OK - */ - AwtBox(Frame frame, String message, boolean addCancelButton) { - super(frame, "Message", true); - setLayout(new BorderLayout()); - TextArea ta = new TextArea(message, 1 + (message.length() - message.replace("\n", "").length()), 90, - TextArea.SCROLLBARS_VERTICAL_ONLY); - ta.setEditable(false); - add("Center", ta); - addOKCancelPanel(addCancelButton); - createFrame(); - pack(); - setVisible(true); - } - - AwtBox(Frame frame, String msg) { - this(frame, msg, false); - } - - private void addOKCancelPanel(boolean okcan) { - Panel p = new Panel(); - p.setLayout(new FlowLayout()); - createOKButton(p); - if (okcan == true) - createCancelButton(p); - add("South", p); - } - - private void createOKButton(Panel p) { - p.add(okButton = new Button("OK")); - okButton.addActionListener(this); - } - - private void createCancelButton(Panel p) { - p.add(cancelButton = new Button("Cancel")); - cancelButton.addActionListener(this); - } - - private void createFrame() { - Dimension d = getToolkit().getScreenSize(); - setLocation(d.width / 3, d.height / 3); - } - - @Override - public void actionPerformed(ActionEvent ae) { - if (ae.getSource() == okButton) { - okClicked = true; - setVisible(false); - } else if (ae.getSource() == cancelButton) { - setVisible(false); - } - this.dispose(); - } - -} diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java index 0d14a3b9..5bce8d9f 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java @@ -1,35 +1,38 @@ package org.openslx.dozmod.gui; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.lang.reflect.InvocationTargetException; import java.util.concurrent.atomic.AtomicReference; +import javax.management.monitor.Monitor; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.SwingUtilities; + import org.apache.log4j.Logger; -import org.eclipse.swt.SWT; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.widgets.Display; -import org.eclipse.swt.widgets.MessageBox; -import org.eclipse.swt.widgets.Monitor; -import org.eclipse.swt.widgets.Shell; import org.openslx.dozmod.gui.helper.MessageType; +import org.openslx.util.QuickTimer; public class Gui { private static final Logger LOGGER = Logger.getLogger(Gui.class); - /** - * The one and only display to use throughout the application - */ - public static final Display display = new Display(); - - /** - * All active shells - we don't use display.getShells() as it is slow... - */ - private static final List shells = new ArrayList<>(); - - private static volatile int exitCode = 0; + private static Rectangle clientArea(GraphicsDevice gd) { + Insets inset = Toolkit.getDefaultToolkit().getScreenInsets(gd.getDefaultConfiguration()); + Rectangle bounds = gd.getDefaultConfiguration().getBounds(); + bounds.x += inset.left; + bounds.y += inset.top; + bounds.width -= (inset.top + inset.bottom); + bounds.height -= (inset.left + inset.right); + return bounds; + } /** * Center the given shell on the {@link Monitor} it is displayed on. @@ -37,9 +40,9 @@ public class Gui { * * @param shell Some shell */ - public static void centerShell(Shell shell) { - Monitor activeMonitor = getMonitorFromRectangle(shell.getBounds(), true); - Rectangle bounds = activeMonitor.getClientArea(); + public static void centerShell(JFrame shell) { + GraphicsDevice activeMonitor = getMonitorFromRectangle(shell.getBounds(), true); + Rectangle bounds = clientArea(activeMonitor); Rectangle rect = shell.getBounds(); int x = bounds.x + (bounds.width - rect.width) / 2; int y = bounds.y + (bounds.height - rect.height) / 2; @@ -52,7 +55,7 @@ public class Gui { * @param parent Parent shell, used as reference * @param shellToCenter The shell that should be repositioned */ - public static void centerShellOverShell(Shell parent, Shell shellToCenter) { + public static void centerShellOverShell(JFrame parent, JFrame shellToCenter) { Rectangle bounds = parent.getBounds(); Rectangle rect = shellToCenter.getBounds(); int x = bounds.x + (bounds.width - rect.width) / 2; @@ -65,14 +68,15 @@ public class Gui { } /** - * Make sure the given shell fits the {@link Monitor} it is displayed on. + * Make sure the given shell fits the {@link GraphicsDevice} it is displayed + * on. * * @param shell Some shell */ - public static void limitShellSize(Shell shell) { - Monitor activeMonitor = getMonitorFromRectangle(shell.getBounds(), true); - Rectangle bounds = activeMonitor.getClientArea(); - Rectangle rect = shell.getBounds(); + public static void limitShellSize(JFrame window) { + GraphicsDevice activeMonitor = getMonitorFromRectangle(window.getBounds(), true); + Rectangle bounds = clientArea(activeMonitor); + Rectangle rect = window.getBounds(); boolean changed = false; if (rect.width + 20 > bounds.width) { rect.width = bounds.width - 20; @@ -83,8 +87,8 @@ public class Gui { changed = true; } if (changed) { - shell.setSize(rect.width, rect.height); - rect = shell.getBounds(); + window.setSize(rect.width, rect.height); + rect = window.getBounds(); } changed = false; if (rect.x + rect.width >= bounds.x + bounds.width) { @@ -96,7 +100,7 @@ public class Gui { changed = true; } if (changed) { - shell.setLocation(rect.x, rect.y); + window.setLocation(rect.x, rect.y); } } @@ -108,18 +112,18 @@ public class Gui { * primary monitor if true, null otherwise * @return the {@link Monitor} */ - public static Monitor getMonitorFromPoint(Point point, boolean defaultToPrimary) { + private static GraphicsDevice getMonitorFromPoint(GraphicsDevice[] screens, Point point, + boolean defaultToPrimary) { LOGGER.debug("Finding monitor for point " + point.toString()); - Monitor[] monitors = display.getMonitors(); - for (Monitor monitor : monitors) { - Rectangle bounds = monitor.getBounds(); + for (GraphicsDevice dev : screens) { + Rectangle bounds = dev.getDefaultConfiguration().getBounds(); LOGGER.debug("Checking monitor " + bounds.toString()); if (bounds.contains(point)) - return monitor; + return dev; } if (defaultToPrimary) { LOGGER.debug("Defaulting to primary..."); - return display.getPrimaryMonitor(); + return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice(); } return null; } @@ -132,10 +136,14 @@ public class Gui { * primary monitor if true, null otherwise * @return the {@link Monitor} */ - public static Monitor getMonitorFromRectangle(Rectangle rect, boolean defaultToPrimary) { + private static GraphicsDevice getMonitorFromRectangle(Rectangle rect, boolean defaultToPrimary) { // Make sure rectangle is in bounds. This is not completely accurate // in case there are multiple monitors that have different resolutions. - Rectangle bounds = display.getBounds(); + GraphicsDevice[] screens = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); + Rectangle bounds = new Rectangle(); + for (GraphicsDevice dev : screens) { + bounds.union(dev.getDefaultConfiguration().getBounds()); + } LOGGER.debug("Display bounds are " + bounds.toString() + ", rect is " + rect.toString()); if (rect.x + rect.width >= bounds.x + bounds.width) { rect.width -= (rect.x + rect.width) - (bounds.x + bounds.width); @@ -157,7 +165,7 @@ public class Gui { } LOGGER.debug("After correction: " + rect.toString()); // Now just use the same code as *FromPoint by using the rectangle's center - return getMonitorFromPoint(new Point(rect.x + rect.width / 2, rect.y + rect.height / 2), + return getMonitorFromPoint(screens, new Point(rect.x + rect.width / 2, rect.y + rect.height / 2), defaultToPrimary); } @@ -170,16 +178,28 @@ public class Gui { */ public static T syncExec(final GuiCallable task) { final AtomicReference instance = new AtomicReference<>(); - display.syncExec(new Runnable() { - @Override - public void run() { - try { - instance.set(task.run()); - } catch (Throwable e) { - LOGGER.warn("syncExec failed!", e); + final AtomicReference thrown = new AtomicReference<>(); + if (SwingUtilities.isEventDispatchThread()) { + return task.run(); + } + try { + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + try { + instance.set(task.run()); + } catch (Throwable e) { + thrown.set(e); + } } - } - }); + }); + } catch (InvocationTargetException | InterruptedException e) { + LOGGER.warn("syncExec() failed", e); + return null; + } + if (thrown.get() != null) { + throw new RuntimeException("task passed to syncExec() failed", thrown.get()); + } return instance.get(); } @@ -190,7 +210,7 @@ public class Gui { * @param task Task to run */ public static void asyncExec(final Runnable task) { - display.asyncExec(task); + SwingUtilities.invokeLater(task); } /** @@ -202,94 +222,44 @@ public class Gui { T run(); } + /** + * Exit application - dispose all shells, so mainloop will terminate. + * + * @param code + */ + public static void exit(int code) { + QuickTimer.cancel(); + Window[] ownerlessWindows = Frame.getOwnerlessWindows(); + for (Window w : ownerlessWindows) { + w.dispose(); + } + System.exit(code); + } + /** * Generic helper to show a message box to the user, and optionally log the * message to the log file. * - * @param parent parent shell this message box belongs to - * @param message Message to display. Can be multiline. + * @param message Message to display. Can be multi line. * @param messageType Type of message (warning, information) * @param logger Logger instance to log to. Can be null. * @param exception Exception related to this message. Can be null. - * @return true if OK, YES or RETRY was clicked, false for CANCEL or NO + * @return true if OK or YES was clicked, false for CANCEL/NO/(X) */ - public static boolean showMessageBox(Shell parent, String message, MessageType messageType, - Logger logger, Throwable exception) { + public static boolean showMessageBox(String message, MessageType messageType, Logger logger, + Throwable exception) { if (logger != null) logger.log(messageType.logPriority, message, exception); if (exception != null) message += "\n\n" + exception.getClass().getSimpleName() + "\n" + exception.getMessage() + "\n" + " (Siehe Logdatei)"; - MessageBox box = new MessageBox(parent, messageType.style); - box.setMessage(message); - box.setText(messageType.title); - int ret = box.open(); - return ret == SWT.OK || ret == SWT.RETRY || ret == SWT.YES; - } - - /** - * Run the GUI mainloop as long as a window exists. This method does not - * return. - */ - public static void mainloop() { - do { - Iterator it = shells.iterator(); - while (it.hasNext()) { - if (it.next().isDisposed()) - it.remove(); - } - if (!display.readAndDispatch()) - display.sleep(); - } while (!shells.isEmpty()); - display.dispose(); - System.exit(exitCode); - } - - /** - * Exit application - dispose all shells, so mainloop will terminate. - * - * @param code - */ - public static void exit(int code) { - exitCode = code; - asyncExec(new Runnable() { - @Override - public void run() { - for (Shell shell : shells) { - shell.dispose(); - } - } - }); - } - - /** - * Wrapper to get a new shell. This adds the shell to the list of shells, - * which we need to determine whether the app should still be running. - * - * @param style the style of the {@link Shell} - * @return a new {@link Shell} that has no other {@link Shell} as its - * parent. - */ - public static Shell newShell(int style) { - Shell shell = new Shell(display, style); - shells.add(shell); - return shell; - } - - /** - * Wrapper to get a new shell that is a child of another shell. This adds - * the shell to the list of shells, which we need to determine whether the - * app should still be running. - * - * @param parent the parent {@link Shell} - * @param style the style of the {@link Shell} - * @return a new {@link Shell} that has no other {@link Shell} as its - * parent. - */ - public static Shell newShell(Shell parent, int style) { - Shell shell = new Shell(parent, style); - shells.add(shell); - return shell; + if (messageType.buttons == -1) { + JOptionPane.showMessageDialog(null, message, messageType.title, messageType.optionPaneId); + return true; + } + int ret = JOptionPane.showConfirmDialog(null, message, messageType.title, messageType.optionPaneId, + messageType.buttons); + return ret == JOptionPane.OK_OPTION || ret == JOptionPane.YES_OPTION; } } diff --git a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/MessageType.java b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/MessageType.java index d05ac9b9..abff7e21 100644 --- a/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/MessageType.java +++ b/dozentenmodul/src/main/java/org/openslx/dozmod/gui/helper/MessageType.java @@ -1,24 +1,27 @@ package org.openslx.dozmod.gui.helper; +import javax.swing.JOptionPane; + import org.apache.log4j.Level; -import org.eclipse.swt.SWT; public enum MessageType { - DEBUG(SWT.ICON_INFORMATION, "Debug", Level.DEBUG), - INFO(SWT.ICON_INFORMATION, "Hinweis", Level.INFO), - WARNING(SWT.ICON_WARNING, "Warnung", Level.WARN), - WARNING_RETRY(SWT.ICON_WARNING | SWT.CANCEL | SWT.RETRY, "Fehler", Level.ERROR), - ERROR(SWT.ICON_ERROR, "Fehler", Level.ERROR), - ERROR_RETRY(SWT.ICON_ERROR | SWT.CANCEL | SWT.RETRY, "Fehler", Level.ERROR), - QUESTION_YESNO(SWT.ICON_QUESTION | SWT.YES | SWT.NO, "Frage", Level.INFO); + DEBUG(JOptionPane.INFORMATION_MESSAGE, -1, "Debug", Level.DEBUG), + INFO(JOptionPane.INFORMATION_MESSAGE, -1, "Hinweis", Level.INFO), + WARNING(JOptionPane.WARNING_MESSAGE, -1, "Warnung", Level.WARN), + WARNING_RETRY(JOptionPane.WARNING_MESSAGE, JOptionPane.OK_CANCEL_OPTION, "Fehler", Level.ERROR), + ERROR(JOptionPane.ERROR_MESSAGE, -1, "Fehler", Level.ERROR), + ERROR_RETRY(JOptionPane.ERROR_MESSAGE, JOptionPane.OK_CANCEL_OPTION, "Fehler", Level.ERROR), + QUESTION_YESNO(JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION, "Frage", Level.INFO); public final String title; - public final int style; + public final int optionPaneId; public final Level logPriority; + public final int buttons; - private MessageType(int style, String title, Level prio) { + private MessageType(int paneId, int buttons, String title, Level prio) { this.title = title; - this.style = style; + this.optionPaneId = paneId; + this.buttons = buttons; this.logPriority = prio; } } -- cgit v1.2.3-55-g7522