Code-behind class
You can combine an FXML markup file with a Java source code file (called a code-behind class), allowing you to combine declarative markup and imperative code. Simply create two files in the same package:
com/sample/MyControl.fxml
com/sample/MyControl.java
In MyControl.fxml
, add the fx:class
attribute to the root element, and specify the fully-qualified name of the code-behind class.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.StackPane?>
<?import javafx.scene.control.Button?>
<StackPane xmlns="http://javafx.com/javafx" xmlns:fx="http://jfxcore.org/fxml/2.0"
fx:class="com.sample.MyControl">
<Button fx:id="myButton1"/>
</StackPane>
In MyControl.java
, create a new class that extends MyControlBase
.
package com.sample;
public class MyControl extends MyControlBase {
public MyControl() {
initializeComponent();
myButton1.setText("Hello!");
}
}
The
MyControlBase
class is generated by the FXML compiler; it contains the compiled markup of the FXML file. If theMyControlBase
class is missing, run the:processFxml
task in your Gradle build to create the class.By default, the name of the generated markup class corresponds to the name of the FXML file with the
Base
suffix. This can be changed with thefx:markupClassName
attribute.
Initializing the scene graph with initializeComponent
The scene graph specified in the FXML file is initialized by the compiler-generated initializeComponent()
method. It is important that you call this method in the constructor of the code-behind class, as otherwise the components that make up the FXML file will never be instantiated.
You should call
initializeComponent()
after you initialize all of the state which the FXML scene graph depends on, but before you actually access the FXML scene graph.
What is the relationship between fx:class
, fx:controller
, and fx:root
?
fx:controller
and fx:root
are both directives of the FXML 1.0 format, and are not available in the FXML 2.0 format. fx:class
is a new directive that allows combining markup and imperative code. This is similar to the fx:root
directive, but doesn’t require using FXMLLoader
to load the markup at runtime.
FXML 2.0 always compiles down to scene graph nodes; it does not support the markup/controller model of FXML 1.0 out of the box. Instead, it is left to developers to implement their favorite architectural patterns. FXML 2.0 is well-suited to implement patterns like MVC or MVVM.