我有一个JavaFX 8应用程序。它使用一种观察者模式来对事件做出反应:
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));
}
}
到目前为止,我的所有用例都很好用:
Platform.runLater()
发起的线程现在我想启动嵌入式Undertow HTTP服务器并在其中部署JAX-RS端点。每当有请求进入那里时,我想使用上面的事件总线从该端点内发出一个事件。所以,这就是我开始Undertow并部署我的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()
)。
谢谢!
答案 0 :(得分:2)
如果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));
});
}
}