3

我想将 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() 调用中无限期地等待。任何想法为什么?

此代码在 JDK-8 中运行良好,但不适用于 java-11.0.1。

我在这个问题上一无所获,有点卡在 Java11 JavaFX 问题上。代码有问题吗?或 java11 的 javafx 的任何报告问题

4

1 回答 1

5

您正在Scene主线程上设置。从JFXPanel强调我的)的文档中:

有一些相关的限制JFXPanel。作为一个 Swing 组件,它只能从事件调度线程访问,除了方法,它可以在事件调度线程或 JavaFX 应用程序线程上调用setScene(javafx.scene.Scene)

换个setScene电话Platform.runLater(或SwingUtilities.invokeLater)。

Platform.runLater(() -> {
    dummyPanel.setScene(dummyScene);
    System.out.println("Scene Created");
});

请注意,使用您当前的代码,一旦main返回,JVM 将继续运行。创建 a初始化 JavaFX 运行时,直到最后一个窗口关闭(仅当is )或被调用JFXPanel时才会退出。由于您的代码两者都没有,JavaFX 运行时将继续运行。Platform.isImplicitExittruePlatform.exit


的文档JFXPanel还提供了一个如何使用它的示例(注意几乎所有事情都发生在Event Dispatch ThreadJavaFX Application Thread上):

这是如何使用的典型模式JFXPanel

 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();
             }
         });
     }
 }
于 2018-11-16T18:18:31.837 回答