This is a basic project that uses FXML, created with NetBeans (New Project -> JavaFX -> JavaFX FXML Application). It contains just three files:
Main Application class
package org.stackoverflow;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class BasicApplication extends Application {
@Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("BasicFXML.fxml"));
Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
FXML file
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" prefHeight="200" prefWidth="320" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.stackoverflow.BasicFXMLController">
<children>
<Button layoutX="126" layoutY="90" text="Click Me!" onAction="#handleButtonAction" fx:id="button" />
<Label layoutX="126" layoutY="120" minHeight="16" minWidth="69" fx:id="label" />
</children>
</AnchorPane>
Controller
package org.stackoverflow;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
public class BasicFXMLController {
@FXML
private Label label;
public void initialize() {
// TODO
}
@FXML
private void handleButtonAction(ActionEvent event) {
label.setText("Hello World!");
}
}
Run
Building and running the project should display a small window with a clickable button:
How it works
Briefly, in the main Application class, the FXMLLoader will load basicFXML.fxml
from the jar/classpath, as specified by FXMLLoader.load(getClass().getResource("BasicFXML.fxml"))
.
When loading basicFXML.fxml
, the loader will find the name of the controller class, as specified by fx:controller="org.stackoverflow.BasicFXMLController"
in the FXML.
Then the loader will create an instance of that class, in which it will try to inject all the objects that have an fx:id
in the FXML and are marked with the @FXML
annotation in the controller class.
In this sample, the FXMLLoader will create the label based on <Label ... fx:id="label"/>
, and it will inject the label instance into the @FXML private Label label;
.
Finally, when the whole FXML has been loaded, the FXMLLoader will call the controller's initialize
method, and the code that registers an action handler with the button will be executed.
Editing
While the FXML file can be edited within the IDE, it is not recommended, as the IDE provides just basic syntax checking and autocompletion, but not visual guidance.
The best approach is opening the FXML file with Scene Builder, where all the changes will be saved to the file.
Scene Builder can be launched to open the file:
Or the file can be opened with Scene Builder directly from the IDE:
Open
.Open In Scene Builder
.Open with Scene Builder
.If Scene Builder is properly installed and its path added to the IDE (see Remarks below), it will open the file:
Changes can be made by dragging new containers or new controls from the left panes, and properties and layout values can be changed on the right panes.
Note that one of the id tag that allows injecting the FXML into the Java code is fx:id
. It can be set in the Code
pane:
After applying changes, save the file (Scene Builder -> File -> Save). If changes are made editing the file from the IDE, when saving the file, those will be updated on Scene Builder.