我正在将几个
据我所知,JFXPanel构造函数通过调用以下方法启动JavaFX线程:
当
我找到的解决此问题的唯一方法是在Swing应用程序开始时调用
这似乎是JavaFX-Swing交互中的一个错误或至少应该修改交互文档来讨论
另一个解决方案是允许在创建另一个JFXPanel时创建一个新的JavaFX线程,但是被
JFXPanels
嵌入到Swing应用程序中,当这些JFXPanels不再可见时,JavaFX线程会死亡。这是有问题的,因为在JavaFX线程死亡后创建另一个JFXPanel
将不会启动另一个JavaFX线程,因此JFXPanel
将是空白的。据我所知,JFXPanel构造函数通过调用以下方法启动JavaFX线程:
PlatformImpl.startup(new Runnable() {
@Override public void run() {
// No need to do anything here
}
});
稍后,一旦 JFXPanel
有了父组件,它的 addNotify
方法就会被调用,该方法调用 registerFinishListener
并向 PlatformImpl
注册一个 PlatformImpl.FinishListener()
。注册 FinishListener
的行为在调用 PlatformImpl.checkIdle()
时防止 JavaFX 线程死亡。
当一个 JFXPanel
不再可见时,其 removeNotify
方法将被调用,并调用 deregisterFinishListener()
:
private synchronized void deregisterFinishListener() {
if (instanceCount.decrementAndGet() > 0) {
// Other JFXPanels still alive
return;
}
PlatformImpl.removeListener(finishListener);
finishListener = null;
}
当
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();
}
}
我找到的解决此问题的唯一方法是在Swing应用程序开始时调用
Platform.setImplicitExit(false)
,这样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;
}
我有所遗漏吗?