嵌套控制器

无需使用单个控制器在单个 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"));