Kri*_*nom 3 java windows openjfx 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");
}
}
Run Code Online (Sandbox Code Playgroud)
此代码在 setScene() 方法调用中冻结。我尝试调试它,发现它的代码在 JFXPanel.setScene 方法中的 secondaryLoop.enter() 调用中无限期地等待。任何想法为什么?
此代码在 JDK-8 中运行良好,但不适用于 java-11.0.1。
我对这个问题一无所知,有点卡在 Java11 JavaFX 问题上。代码有问题吗?或任何报告的 javafx for java11 问题
您正在Scene主线程上设置。来自JFXPanel(强调我的)的文档:
有一些相关的限制
JFXPanel。作为Swing组件,它应该只从事件调度线程访问,除了该setScene(javafx.scene.Scene)方法,该方法既可以在事件调度线程或JavaFX应用程序线程调用。
裹setScene在一个Platform.runLater呼叫(或SwingUtilities.invokeLater)。
Platform.runLater(() -> {
dummyPanel.setScene(dummyScene);
System.out.println("Scene Created");
});
Run Code Online (Sandbox Code Playgroud)
请注意,使用您当前的代码,一旦main返回,JVM 将继续运行。创建 aJFXPanel初始化 JavaFX 运行时,该运行时在最后一个窗口关闭(仅当Platform.isImplicitExit是true)或被Platform.exit调用时才会退出。由于您的代码两者都没有,JavaFX 运行时将继续运行。
的文档JFXPanel还提供了一个如何使用它的示例(注意几乎所有事情都发生在Event Dispatch Thread或JavaFX Application Thread 上):
这是一个典型的模式如何
JFXPanel使用:Run Code Online (Sandbox Code Playgroud)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(); } }); } }