我正在制作一个在Javafx中有gui的翻译程序。我正在使用JNativeHook来启用应用程序不在焦点时的全局键控系统。当同时按下alt和t时,程序应该从任务栏恢复自身。
但是,当我按下alt和t时,会出现错误,说JNativeHook线程无法使用javafx线程运行。
甚至可以让GlobalScreen线程与javafx线程通信吗?
这是我的全局keylistener代码
GlobalScreen.addNativeKeyListener(listener);
这是我的倾听者
@Override
public void nativeKeyPressed(NativeKeyEvent nativeKeyEvent) {
if(nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_ALT_L){
alt = true;
}
if(nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_T){
t = true;
}
check();
}
@Override
public void nativeKeyReleased(NativeKeyEvent nativeKeyEvent) {
if(nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_ALT_L){
alt = false;
}
if(nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_T){
t = false;
}
}
@Override
public void nativeKeyTyped(NativeKeyEvent nativeKeyEvent) {
}
});
我得到的错误是
Exception in thread "JNativeHook Dispatch Thread" java.lang.IllegalStateException: Not on FX application thread; currentThread = JNativeHook Dispatch Thread
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:204)
如果你不熟悉GlobalScreen,它基本上是在你的java程序没有关注并在你的计算机上使用其他东西时为你的java程序添加一个keylistener。
有什么办法可以让JNativeHook线程访问我的javafx线程,在最小化后用热键重新打开程序?
答案 0 :(得分:3)
将它们包装在Platform.runLater中,使它们在FX线程上运行,即:
Platform.runLater( () -> {
if(nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_ALT_L){
alt = true;
}
if(nativeKeyEvent.getKeyCode() == NativeKeyEvent.VC_T){
t = true;
}
check();
} );
答案 1 :(得分:0)
查看working-with-swing和SwingDispatchService.java课程。您应该能够为JavaFX实现类似的功能。
public class PlatformDispatchService extends AbstractExecutorService {
private boolean running = false;
public SwingDispatchService() {
running = true;
}
public void shutdown() {
running = false;
}
public List<Runnable> shutdownNow() {
running = false;
return new ArrayList<Runnable>(0);
}
public boolean isShutdown() {
return !running;
}
public boolean isTerminated() {
return !running;
}
public boolean awaitTermination(long timeout, TimeUnit unit) throws InterruptedException {
return true;
}
public void execute(Runnable r) {
Platform.runLater(r);
}
}