巢狀控制器

無需使用單個控制器在單個 FXML 中建立整個 UI。

<fx:include> 標籤可用於將一個 fxml 檔案包含到另一個檔案中。包含的 fxml 的控制器可以注入到包含檔案的控制器中,就像 FXMLLoader 建立的任何其他物件一樣。

這是通過將 fx:id 屬性新增到 <fx:include> 元素來完成的。這樣,包含的 fxml 的控制器將被注入到名為 <fx:id value>Controller 的欄位中。

例子:

fx:id 值 注入的欄位名稱
FOO FooController
answer42 answer42Controller
XYZ xYzController

樣本 fxmls

計數器

這是一個包含帶有 Text 節點的 StackPane 的 fxml。此 fxml 檔案的控制器允許獲取當前計數器值以及遞增計數器:

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;
    }
    
}

包括 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

包含的 fxml 的控制器被注入該控制器。這裡 ButtononAction 事件的處理程式用於遞增計數器。

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();
    }

}

假設從與 outer.fxml 相同的包中的類呼叫程式碼,可以像這樣載入 fxmls:

Parent parent = FXMLLoader.load(getClass().getResource("outer.fxml"));