forked from dorkbox/SystemTray
Fixed issues when running JavaFX or SWT on the swing EDT.
This commit is contained in:
parent
bc4d22c586
commit
59669bc867
@ -26,6 +26,8 @@ import java.io.PrintStream;
|
||||
import java.net.URL;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import javax.swing.SwingUtilities;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
@ -573,10 +575,26 @@ class SystemTray implements Menu {
|
||||
}
|
||||
}
|
||||
|
||||
if (isJavaFxLoaded) {
|
||||
// This will initialize javaFX dispatch methods
|
||||
JavaFX.init();
|
||||
}
|
||||
else if (isSwtLoaded) {
|
||||
// This will initialize swt dispatch methods
|
||||
Swt.init();
|
||||
}
|
||||
|
||||
// if it's native + linux, have to do GTK instead. Don't need to be on the dispatch thread though.
|
||||
// _AwtTray must be constructed on the EDT...
|
||||
if (OS.isLinux() && NativeUI.class.isAssignableFrom(trayType) && trayType == _AwtTray.class) {
|
||||
if ((isJavaFxLoaded || isSwtLoaded) && SwingUtilities.isEventDispatchThread()) {
|
||||
// oh boy! This WILL NOT WORK. Let the dev know
|
||||
throw new RuntimeException("SystemTray initialization can not occur on the swing Event Dispatch Thread (EDT)");
|
||||
}
|
||||
|
||||
// javaFX and SWT should not start on the EDT!!
|
||||
|
||||
// if it's linux + native menus must not start on the EDT!
|
||||
// _AwtTray must be constructed on the EDT however...
|
||||
if (isJavaFxLoaded || isSwtLoaded ||
|
||||
(OS.isLinux() && NativeUI.class.isAssignableFrom(trayType) && trayType == _AwtTray.class)) {
|
||||
try {
|
||||
reference.set((Menu) trayType.getConstructors()[0].newInstance(systemTray));
|
||||
logger.info("Successfully Loaded: {}", trayType.getSimpleName());
|
||||
@ -619,7 +637,6 @@ class SystemTray implements Menu {
|
||||
"configuration");
|
||||
}
|
||||
|
||||
|
||||
// These install a shutdown hook in JavaFX/SWT, so that when the main window is closed -- the system tray is ALSO closed.
|
||||
if (ENABLE_SHUTDOWN_HOOK) {
|
||||
if (isJavaFxLoaded) {
|
||||
|
@ -29,24 +29,47 @@ public
|
||||
class JavaFX {
|
||||
|
||||
// Methods are cached for performance
|
||||
private static Method isEventThread;
|
||||
private static Method dispatchMethod;
|
||||
private static final Method dispatchMethod;
|
||||
private static final Method isEventThreadMethod;
|
||||
|
||||
public static
|
||||
void dispatch(final Runnable runnable) {
|
||||
// javafx.application.Platform.runLater(runnable);
|
||||
static {
|
||||
Method _isEventThreadMethod = null;
|
||||
Method _dispatchMethod = null;
|
||||
|
||||
try {
|
||||
if (dispatchMethod == null) {
|
||||
Class<?> clazz = Class.forName("javafx.application.Platform");
|
||||
dispatchMethod = clazz.getMethod("runLater");
|
||||
}
|
||||
Class<?> clazz = Class.forName("javafx.application.Platform");
|
||||
_dispatchMethod = clazz.getMethod("runLater", Runnable.class);
|
||||
|
||||
dispatchMethod.invoke(null, runnable);
|
||||
clazz = Class.forName("javafx.application.Platform");
|
||||
_isEventThreadMethod = clazz.getMethod("isFxApplicationThread");
|
||||
} catch (Throwable e) {
|
||||
if (SystemTray.DEBUG) {
|
||||
SystemTray.logger.error("Cannot initialize JavaFX", e);
|
||||
}
|
||||
}
|
||||
|
||||
dispatchMethod = _dispatchMethod;
|
||||
isEventThreadMethod = _isEventThreadMethod;
|
||||
}
|
||||
|
||||
public static
|
||||
void init() {
|
||||
// empty method to initialize class
|
||||
|
||||
if (dispatchMethod == null || isEventThreadMethod == null) {
|
||||
SystemTray.logger.error("Unable to initialize JavaFX! Please create an issue with your OS and Java " +
|
||||
"version so we may further investigate this issue.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static
|
||||
void dispatch(final Runnable runnable) {
|
||||
// javafx.application.Platform.runLater(runnable);
|
||||
|
||||
try {
|
||||
dispatchMethod.invoke(null, runnable);
|
||||
} catch (Throwable e) {
|
||||
SystemTray.logger.error("Unable to execute JavaFX runLater(). Please create an issue with your OS and Java " +
|
||||
"version so we may further investigate this issue.");
|
||||
}
|
||||
@ -57,15 +80,8 @@ class JavaFX {
|
||||
// javafx.application.Platform.isFxApplicationThread();
|
||||
|
||||
try {
|
||||
if (isEventThread == null) {
|
||||
Class<?> clazz = Class.forName("javafx.application.Platform");
|
||||
isEventThread = clazz.getMethod("isFxApplicationThread");
|
||||
}
|
||||
return (Boolean) isEventThread.invoke(null);
|
||||
return (Boolean) isEventThreadMethod.invoke(null);
|
||||
} catch (Throwable e) {
|
||||
if (SystemTray.DEBUG) {
|
||||
SystemTray.logger.error("Cannot initialize JavaFX", e);
|
||||
}
|
||||
SystemTray.logger.error("Unable to check if JavaFX is in the event thread. Please create an issue with your OS and Java " +
|
||||
"version so we may further investigate this issue.");
|
||||
}
|
||||
|
@ -15,6 +15,10 @@
|
||||
*/
|
||||
package dorkbox.systemTray.util;
|
||||
|
||||
import static dorkbox.systemTray.SystemTray.logger;
|
||||
|
||||
import org.eclipse.swt.widgets.Display;
|
||||
|
||||
/**
|
||||
* Utility methods for SWT.
|
||||
* <p>
|
||||
@ -22,16 +26,31 @@ package dorkbox.systemTray.util;
|
||||
*/
|
||||
public
|
||||
class Swt {
|
||||
private static final Display currentDisplay;
|
||||
|
||||
static {
|
||||
// we have to save this, otherwise it is "null" when methods are run from the swing EDT.
|
||||
currentDisplay = Display.getCurrent();
|
||||
}
|
||||
|
||||
|
||||
public static
|
||||
void init() {
|
||||
// empty method to initialize class
|
||||
if (currentDisplay == null) {
|
||||
logger.error("Unable to get the current display for SWT. Please create an issue with your OS and Java " +
|
||||
"version so we may further investigate this issue.");
|
||||
};
|
||||
}
|
||||
|
||||
public static
|
||||
void dispatch(final Runnable runnable) {
|
||||
org.eclipse.swt.widgets.Display.getCurrent()
|
||||
.syncExec(runnable);
|
||||
currentDisplay.syncExec(runnable);
|
||||
}
|
||||
|
||||
public static
|
||||
void onShutdown(final Runnable runnable) {
|
||||
org.eclipse.swt.widgets.Display.getCurrent()
|
||||
.getShells()[0].addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() {
|
||||
currentDisplay.getShells()[0].addListener(org.eclipse.swt.SWT.Close, new org.eclipse.swt.widgets.Listener() {
|
||||
@Override
|
||||
public
|
||||
void handleEvent(final org.eclipse.swt.widgets.Event event) {
|
||||
|
Loading…
Reference in New Issue
Block a user