I want to integrate openjfx into my Java 11 code. Using IntelliJ IDEA 2018.2.6 on Windows 10, I created a test project and tried out below code
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");
}
}
this code is freezing in setScene() method call. I tried debugging it and found that it the code wait indefinitely in secondaryLoop.enter() call in JFXPanel.setScene method. any Idea why?
This code works fine in JDK-8 but not working with java-11.0.1.
I am getting nowhere with this issue, kind of stuck at the Java11 JavaFX problem. Is there something wrong with the code? or any reported issue with javafx for java11
You're setting the Scene
on the main thread. From the documentation of JFXPanel
(emphasis mine):
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.
Wrap setScene
in a Platform.runLater
call (or SwingUtilities.invokeLater
).
Platform.runLater(() -> {
dummyPanel.setScene(dummyScene);
System.out.println("Scene Created");
});
Note that, with your current code, once main
returns the JVM will continue to run. Creating a JFXPanel
initializes the JavaFX runtime which won't exit until that last window is closed (only when Platform.isImplicitExit
is true
) or Platform.exit
is called. Since your code does neither, the JavaFX runtime will keep running.
The documentation of JFXPanel
also gives an example of how it expects to be used (note nearly everything happens on either the Event Dispatch Thread or JavaFX Application Thread):
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(); } }); } }