Including other FXML files

You can include one FXML in another, as shown in the following code:

<?import javafx.scene.layout.*?>
<HBox xmlns:fx="http://javafx.com/fxml">
<children>
<fx:include source="my_fields.fxml"/>
<TextField fx:id="textField" />
<Button fx:id="button" text="Button" />
</children>
</HBox>

Here, my_fields.xml contains all the listed data:

<?import javafx.scene.control.*?>
<Label text="Label" />

Note that in this document, Label is a root element for simplicity. But, if you want to have several controls, you'll have to introduce a layout manager to handle them—there can be only one root element in the FXML.

But, what to do if the included FXML has its own Controller? They are called nested controllers and can be handled through the fx:id attribute, similar to regular JavaFX classes.

First of all, you need to set a name for your include:

<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<HBox xmlns:fx="http://javafx.com/fxml" fx:controller="chapter4.includes.FirstController">
<children>
<fx:include fx:id="myLabel" source="MyLabel.fxml"/>
<TextField fx:id="textField" />
<Button text="Button" onAction="#btnAction"/>
</children>
</HBox>

Now, let's create a slightly more sophisticated MyLabel FXML with a Controller:

<?import javafx.scene.layout.*?>
<?import javafx.scene.control.*?>
<VBox xmlns:fx="http://javafx.com/fxml" fx:controller="chapter4.includes.NestedController">
<Label text="MyLabel" />
<Button fx:id="myBtn" text="I'm nested" onAction="#myBtnAction" />
</VBox>

And, NestedController provides a small API to alter its button:

// chapter4/includes/NestedController.java
public class NestedController implements Initializable {

@FXML
private Button myBtn;

@FXML
void myBtnAction(ActionEvent event) {
System.out.println("Hello from " + myBtn.getText());
}

public void setButtonText(String text) {
myBtn.setText(text);
}

@Override
public void initialize(URL url, ResourceBundle rb) {
}
}

Now, in the controller for the first FXML, we can use that API:

// chapter4/includes/FirstController.java
public class FirstController implements Initializable {

@FXML
private NestedController myLabelController; // name is tricky! See below.

@FXML
void btnAction(ActionEvent event) {
myLabelController.setButtonText(textField.getText());
}

@FXML
private TextField textField;


@Override
public void initialize(URL url, ResourceBundle rb) {
}
}

Note that the name of the corresponding variable should be the corresponding fx:id value concatenated with the Controller word.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.159.82