代码之家  ›  专栏  ›  技术社区  ›  Krishnom

JFX面板用Java 11冻结场景

  •  2
  • Krishnom  · 技术社区  · 6 年前

    我想把OpenJFX集成到我的Java 11代码中。在Windows10上使用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问题上。代码有问题吗?或JavaFX针对Java11报告的任何问题

    1 回复  |  直到 6 年前
        1
  •  4
  •   Slaw    6 年前

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

    有一些限制与 JFX面板 .作为一个Swing组件,它只能从事件调度线程访问,除非 这个 setScene(javafx.scene.Scene) 方法,可以在事件调度线程或JavaFX应用程序线程上调用。

    包裹 setScene 在一个 Platform.runLater 呼叫(或) SwingUtilities.invokeLater )。

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

    请注意,使用当前代码, main 返回JVM将继续运行。创建一个 JFX面板 初始化JavaFX运行时,直到最后一个窗口关闭后才会退出(仅当 Platform.isImplicitExit true Platform.exit 被称为。因为您的代码两者都不做,所以javafx运行时将继续运行。


    文件 JFX面板 还提供了一个如何使用它的示例(注意,几乎所有事情都发生在 事件调度线程 JavaFX应用线程 ):

    下面是一个典型的模式如何 JFX面板 可以使用:

     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();
                 }
             });
         }
     }