summaryrefslogtreecommitdiffstats
path: root/dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java
diff options
context:
space:
mode:
Diffstat (limited to 'dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java')
-rw-r--r--dozentenmodul/src/main/java/org/openslx/dozmod/gui/Gui.java224
1 files changed, 97 insertions, 127 deletions
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<Shell> 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, <code>null</code> 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, <code>null</code> 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> T syncExec(final GuiCallable<T> task) {
final AtomicReference<T> 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<Throwable> 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);
}
/**
@@ -203,93 +223,43 @@ public class Gui {
}
/**
+ * 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<Shell> 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;
}
}