从线程库启动的线程更新JavaFX控件
问题描述:
我有一个JavaFX 8应用程序。它采用一种观察者模式对事件做出反应:从线程库启动的线程更新JavaFX控件
public class EventBus {
public static final EventBus INSTANCE = new EventBus();
private final Set<EventListener> listeners;
private EventBus() {
listeners = new HashSet<>();
}
public void register(EventListener listener) {
listeners.add(listener);
}
public void fire(Event event) {
listeners.forEach(listener -> listener.eventFired(event));
}
}
它工作得很好,到目前为止我所有usecases:
- 带有按钮的互动从外部控制器,这是我与观察
- 活动
Platform.runLater()
发起螺纹 - 等
现在我要开始电子商务嵌入Undertow HTTP服务器并在内部部署JAX-RS端点。每当有请求进入时,我想使用上述事件总线从该端点内发起一个事件。所以,我这是怎么开始暗流和部署我的JAX-RS应用:
UndertowJaxrsServer server = new UndertowJaxrsServer().start();
server.deploy(new MyEndpoint(eventBus));
的事情是,new UndertowJaxrsServer().start()
是异步调用,并启动其自身的线程。然后,当MyEndpoint
处理请求并尝试触发事件时,它会发生在由Undertow启动的该线程中。
所以在事件侦听器,如果我尝试做UI上的任何更新,我得到:
java.lang.IllegalStateException: Not on FX application thread; currentThread = XNIO-1 task-1
at com.sun.javafx.tk.Toolkit.checkFxUserThread(Toolkit.java:236)
at com.sun.javafx.tk.quantum.QuantumToolkit.checkFxUserThread(QuantumToolkit.java:423)
at javafx.scene.Parent$2.onProposedChange(Parent.java:367)
at com.sun.javafx.collections.VetoableListDecorator.clear(VetoableListDecorator.java:294)
at ui.DialogManager.showDialog(DialogManager.java:109)
最后,我的问题是有没有办法明确告诉的JavaFX运行一段代码在UI线程中,即使调用堆栈来自另一个(我没有控制权并且我无法做到这一点)Platform.runLater()
。
谢谢!
答
如果MyEndpoint
是你的类,然后围绕fire(Event event)
方法的调用与Platform.runLater()
或更改EventBus
类:
public class EventBus {
public static final EventBus INSTANCE = new EventBus();
private final Set<EventListener> listeners;
private EventBus() {
listeners = new HashSet<>();
}
public void register(EventListener listener) {
listeners.add(listener);
}
public void fire(Event event) {
Platform.runLater(() -> {
listeners.forEach(listener -> listener.eventFired(event));
});
}
}
作为优化你也可以运行火,[Platform.isFXApplicationThread()](HTTPS内的检查: //docs.oracle.com/javase/8/javafx/api/javafx/application/Platform.html#isFxApplicationThread--),如果没有在FX线程上运行,就运行,否则立即执行。 – jewelsea
非常感谢!第一个提案(围绕“fire(Event event)”的调用)非常完美! – ivko