There is no need to create the whole UI in a single FXML using a single controller.
The <fx:include>
tag can be used to include one fxml file into another. The controller of the included fxml can be injected into the controller of the including file just as any other object created by the FXMLLoader
.
This is done by adding the fx:id
attribute to the <fx:include>
element. This way the controller of the included fxml will be injected to the field with the name <fx:id value>Controller
.
Examples:
fx:id value | field name for injection |
---|---|
foo | fooController |
answer42 | answer42Controller |
xYz | xYzController |
Sample fxmls
Counter
This is a fxml containing a StackPane
with a Text
node. The controller for this fxml file allows getting the current counter value as well as incrementing the counter:
counter.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.text.*?>
<?import javafx.scene.layout.*?>
<StackPane prefHeight="200" prefWidth="200" xmlns:fx="http://javafx.com/fxml/1" fx:controller="counter.CounterController">
<children>
<Text fx:id="counter" />
</children>
</StackPane>
CounterController
package counter;
import javafx.fxml.FXML;
import javafx.scene.text.Text;
public class CounterController {
@FXML
private Text counter;
private int value = 0;
public void initialize() {
counter.setText(Integer.toString(value));
}
public void increment() {
value++;
counter.setText(Integer.toString(value));
}
public int getValue() {
return value;
}
}
Including fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<BorderPane prefHeight="500" prefWidth="500" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="counter.OuterController">
<left>
<Button BorderPane.alignment="CENTER" text="increment" onAction="#increment" />
</left>
<center>
<!-- content from counter.fxml included here -->
<fx:include fx:id="count" source="counter.fxml" />
</center>
</BorderPane>
OuterController
The controller of the included fxml is injected to this controller. Here the handler for the onAction
event for the Button
is used to increment the counter.
package counter;
import javafx.fxml.FXML;
public class OuterController {
// controller of counter.fxml injected here
@FXML
private CounterController countController;
public void initialize() {
// controller available in initialize method
System.out.println("Current value: " + countController.getValue());
}
@FXML
private void increment() {
countController.increment();
}
}
The fxmls can be loaded like this, assuming the code is called from a class in the same package as outer.fxml
:
Parent parent = FXMLLoader.load(getClass().getResource("outer.fxml"));