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