JFXPanel setScene 冻结 java 11
JFXPanel setScene freezing with java 11
我想将 openjfx 集成到我的 Java 11 代码中。在 Windows 10 上使用 IntelliJ IDEA 2018.2.6,我创建了一个测试项目并尝试了以下代码
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.TabPane;
public class Java11FXTestApplication {
public static void main(String[] args) {
JFXPanel dummyPanel;
TabPane dummyTabPane;
Scene dummyScene;
System.out.println("Creating JFX Panel");
dummyPanel = new JFXPanel();
System.out.println("Creating TabPane");
dummyTabPane = new TabPane();
System.out.println("Creating Scene");
dummyScene = new Scene(dummyTabPane);
System.out.println("Setting Scene");
dummyPanel.setScene(dummyScene); //Freezing here
System.out.println("Scene Created");
}
}
此代码在 setScene() 方法调用中冻结。
我尝试调试它,发现它的代码在 JFXPanel.setScene 方法的 secondaryLoop.enter() 调用中无限期等待。知道为什么吗?
This code works fine in JDK-8 but not working with java-11.0.1.
我对这个问题毫无进展,有点卡在 Java11 JavaFX 问题上。代码有问题吗?或 java11
的任何已报告的 javafx 问题
您正在主线程上设置 Scene
。来自 JFXPanel
的文档(强调 我的):
There are some restrictions related to JFXPanel
. As a Swing component, it should only be accessed from the event dispatch thread, except the setScene(javafx.scene.Scene)
method, which can be called either on the event dispatch thread or on the JavaFX application thread.
在 Platform.runLater
调用(或 SwingUtilities.invokeLater
)中包装 setScene
。
Platform.runLater(() -> {
dummyPanel.setScene(dummyScene);
System.out.println("Scene Created");
});
请注意,使用您当前的代码,一旦 main
returns,JVM 将继续 运行。创建一个 JFXPanel
初始化 JavaFX 运行time,直到最后一个 window 关闭(仅当 Platform.isImplicitExit
为 true
时)或 Platform.exit
被调用。由于您的代码两者都没有,因此 JavaFX 运行time 将保持 运行ning.
JFXPanel
的文档还给出了一个示例,说明它的预期使用方式(注意几乎所有事情都发生在 事件调度线程 或 JavaFX 应用线程):
Here is a typical pattern how JFXPanel
can used:
public class Test {
private static void initAndShowGUI() {
// This method is invoked on Swing thread
JFrame frame = new JFrame("FX");
final JFXPanel fxPanel = new JFXPanel();
frame.add(fxPanel);
frame.setVisible(true);
Platform.runLater(new Runnable() {
@Override
public void run() {
initFX(fxPanel);
}
});
}
private static void initFX(JFXPanel fxPanel) {
// This method is invoked on JavaFX thread
Scene scene = createScene();
fxPanel.setScene(scene);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
initAndShowGUI();
}
});
}
}
我想将 openjfx 集成到我的 Java 11 代码中。在 Windows 10 上使用 IntelliJ IDEA 2018.2.6,我创建了一个测试项目并尝试了以下代码
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.control.TabPane;
public class Java11FXTestApplication {
public static void main(String[] args) {
JFXPanel dummyPanel;
TabPane dummyTabPane;
Scene dummyScene;
System.out.println("Creating JFX Panel");
dummyPanel = new JFXPanel();
System.out.println("Creating TabPane");
dummyTabPane = new TabPane();
System.out.println("Creating Scene");
dummyScene = new Scene(dummyTabPane);
System.out.println("Setting Scene");
dummyPanel.setScene(dummyScene); //Freezing here
System.out.println("Scene Created");
}
}
此代码在 setScene() 方法调用中冻结。 我尝试调试它,发现它的代码在 JFXPanel.setScene 方法的 secondaryLoop.enter() 调用中无限期等待。知道为什么吗?
This code works fine in JDK-8 but not working with java-11.0.1.
我对这个问题毫无进展,有点卡在 Java11 JavaFX 问题上。代码有问题吗?或 java11
的任何已报告的 javafx 问题您正在主线程上设置 Scene
。来自 JFXPanel
的文档(强调 我的):
There are some restrictions related to
JFXPanel
. As a Swing component, it should only be accessed from the event dispatch thread, except thesetScene(javafx.scene.Scene)
method, which can be called either on the event dispatch thread or on the JavaFX application thread.
在 Platform.runLater
调用(或 SwingUtilities.invokeLater
)中包装 setScene
。
Platform.runLater(() -> {
dummyPanel.setScene(dummyScene);
System.out.println("Scene Created");
});
请注意,使用您当前的代码,一旦 main
returns,JVM 将继续 运行。创建一个 JFXPanel
初始化 JavaFX 运行time,直到最后一个 window 关闭(仅当 Platform.isImplicitExit
为 true
时)或 Platform.exit
被调用。由于您的代码两者都没有,因此 JavaFX 运行time 将保持 运行ning.
JFXPanel
的文档还给出了一个示例,说明它的预期使用方式(注意几乎所有事情都发生在 事件调度线程 或 JavaFX 应用线程):
Here is a typical pattern how
JFXPanel
can used:public class Test { private static void initAndShowGUI() { // This method is invoked on Swing thread JFrame frame = new JFrame("FX"); final JFXPanel fxPanel = new JFXPanel(); frame.add(fxPanel); frame.setVisible(true); Platform.runLater(new Runnable() { @Override public void run() { initFX(fxPanel); } }); } private static void initFX(JFXPanel fxPanel) { // This method is invoked on JavaFX thread Scene scene = createScene(); fxPanel.setScene(scene); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { initAndShowGUI(); } }); } }