我嵌入了几个JFXPanels
当 JFXPanel 不再可见时,JavaFX 线程就会终止。这是有问题的,因为创建另一个JFXPanel
JavaFX 线程死亡后不会启动另一个 JavaFX 线程,因此JFXPanel
将是空白的。
据我所知,JFXPanel ctor 通过调用以下命令启动 JavaFX 线程:
PlatformImpl.startup(new Runnable() {
@Override public void run() {
// No need to do anything here
}
});
后来有一次JFXPanel
有一个父组件addNotify
调用方法,该方法调用registerFinishListener
它注册了一个PlatformImpl.FinishListener()
with PlatformImpl
。登记行为FinishListener
防止 JavaFX 线程在以下情况下死亡PlatformImpl.checkIdle()
叫做。
When a JFXPanel
不再可见其removeNotify
方法是调用它调用deregisterFinishListener()
:
private synchronized void deregisterFinishListener() {
if (instanceCount.decrementAndGet() > 0) {
// Other JFXPanels still alive
return;
}
PlatformImpl.removeListener(finishListener);
finishListener = null;
}
When instanceCount
为零FinishListener
被删除,这会导致PlatformImpl
打电话PlatformImpl.tkExit
下面的代码会导致 JavaFX 线程终止:
private static void notifyFinishListeners(boolean exitCalled) {
// Notify listeners if any are registered, else exit directly
if (listenersRegistered.get()) {
for (FinishListener l : finishListeners) {
if (exitCalled) {
l.exitCalled();
} else {
l.idle(implicitExit);
}
}
} else if (implicitExit || platformExit.get()) {
tkExit();
}
}
我发现解决此问题的唯一方法是致电Platform.setImplicitExit(false)
在 Swing 应用程序开始时,以便 JavaFX 线程永远不会自动终止。此修复需要调用Platform.exit()
当应用程序退出时,否则 JavaFX 线程将阻止进程停止。
这似乎是 JavaFX-Swing 互操作中的一个错误,或者至少应该修改互操作文档以通过讨论来解决这个问题Platform.setImplicitExit(false)
.
另一种解决方案是允许在创建另一个 JFXPanel 但被阻止时创建新的 JavaFX 线程PlatformImpl.startup(Runnable)
:
if (initialized.getAndSet(true)) {
// If we've already initialized, just put the runnable on the queue.
runLater(r);
return;
}
我错过了什么吗?