If you want to use JavaFX, there are essentially two ways you can do so. The first is to create a standard JavaFX project that extends the Application class, and the second is to use the JFXPanel class which extends JComponent, allowing you to use JavaFX in a Swing application.
To quickly get started, my best advice would be to make sure you have an up-to-date JDK with JavaFX, then install NetBeans and create a new JavaFX project using the templates that are provided.
Simply click to create a New Project, select JavaFX from the provided categories, and you will have a choice of 4 Projects. As this post is about the JFXPanel, I’m going to create a JavaFX in Swing Application.
This provides us with a nice “Hello World” style application making use of the JFXPanel.
If you compare this project with the one that you get when you create a new “JavaFX Application” project, you will notice that they are very similar – you are provided with a Scene to modify in both projects
The key difference is that in the normal JavaFX Application you call setScene(scene); on the Stage object given to you in the start method, but in the JavaFX in Swing Application you call setScene(scene); on the JFXPanel object.
As both projects use a Scene, can both be treated equally from there onwards? Unfortunately, if you’re using the JFXPanel you’re going to have the be a little more careful with what you are doing as you are now dealing with two different Threads – the Swing Thread, and the JavaFX Thread.
You will notice in the JavaFX in Swing Application that the Scene is created and set in a Runnable:
Platform.runLater(new Runnable() {
@Override
public void run() {
createScene();
}
});
The reason for this is that we need to make sure we are doing the Swing stuff on the Swing Thread, and the JavaFX stuff on the JavaFX Thread.
This is important, and you need to remember to use Platform.runLater() if you are ever modifying the Scene from anywhere but the JavaFX Thread, for example in your Swing code or from within a Thread. Not doing so may work, but sooner or later you will run into trouble because the Scene is not Thread safe.
I recommend reading the JFXPanel and Task Class API documentation if you wish to find out more.
Something else that I have run into while playing with the JFXPanel is what happens when you no longer want the JFXPanel in your Swing application – or rather when you no longer want it, and then you do again.
When I was converting the PageFlow mode from Java3D to JavaFX in our Java PDF Viewer, one of the problems I had was that if you were to exit the JavaFX PageFlow mode and then go back into it later, it would not allow it and would provide the error message below:
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Platform.exit has been called
The cause for this is that once you are finished with the JFXPanel, the JavaFX thread may be implicitly exited. This is an issue if you then want to use it again because unfortunately, you cannot restart it once it has been exited.
To fix this issue, you need to add the following line:
Platform.setImplicitExit(false);
And you will now be able to throw away your JFXPanel and create a new one.
For now, that’s all the advice I have! I have written several articles on what I have learned from converting our Java3D usage into JavaFX. Make sure to check them out!