I was looking for a framework similar to WPF in the .net world or to the Android’s approach: design the UI within an XML document and automatically wire it up to its controller and to its model. Since I have had a longer break in Java, the last thing I knew was Swing and SWT. The first research in the Internet gave the answer: JavaFX.
* it was 20 years ago: you want to focus on your code, on your business logic, but no… First, you have to dance this odd dance with setting classpath, java home, path and you have no idea, where the JVM was looking for the classes that it could not find. Now, a dejavu: classpath seems to be good now, but we have modules that can’t be found. More about it just below.
You will need an appropriate JDK version and the JavaFX itself. It seems, it has changed over the time and (probably) only the JRE/JDK 8 did include JavaFX. My choice was JDK 14 and JavaFX 15, although I’ve set the code compatibility down to 11.
I’m used to Eclipse, so that was my IDE of choice. First, create a new project of a Maven type. It is not a must, but makes a lot of things easier.
Both, Eclipse and Maven do control the dependencies and a few other aspects of the project. For as long as they are in-sync, everything works fine. Good practice is to trust Maven and to try configure the project only via the pom.xml.
First, set the correct Java version, for example 11:
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
Then, insert dependencies to JavaFX:
Create a class that extends the javafx.application.Application and that declares a standard main() method, containing only the following:
public static void main(String[] args) {
launch(args);
}
The start() method that you have to override could contain the following in the first step:
FXMLLoader loader = new FXMLLoader();
loader.setController(this);
loader.setLocation(getClass().getResource("Test.fxml"));
VBox vbox = (VBox)loader.load();
Scene scene = new Scene(vbox);
primaryStage.setScene(scene);
primaryStage.setTitle("Test");
primaryStage.show();
Next, create a new Test.fxml file in the same package:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<VBox xmlns:fx="http://javafx.com/fxml/1" prefWidth="300" prefHeight="200">
<Label fx:id="myLabel" text="All your base are belong to us." />
</VBox>
Assuming that you don’t use any special FXML editor, you need to enter the import statements by yourself.
The only magic is the id attribute that will automatically wire the label to a corresponding field in the controller’s class. In order to test it, create the field:
@FXML private Label myLabel;
How to test it’s working? For example, try to print out the value of the label. Add the line before calling the show() method:
System.out.println(myLabel.getText());
A simple Run as Java Application within Eclipse should do the trick. Most probably you will see the error first:
Error: JavaFX runtime components are missing, and are required to run this application
You need to tell the JVM where to look for the JavaFX modules. This can be achieved by providing this parameter (adapt the /javafx/lib to your needs):
--module-path /javafx/lib --add-modules=javafx.controls,javafx.fxml
Some of JavaFX releases (e.g. the early access) do name their files in a way they can’t be found (e.g. javafx-base-16-ea+1.jar instead of javafx.base.jar). You can map them by by telling the JVM the correct names:
–patch-module javafx.fxml=/your-path/javafx-fxml-16-ea+1-win.jar –patch-module javafx.controls=/your-path/javafx-controls-16-ea+1-win.jar
In the upcoming posts I will cover next steps: