FXML 声明的自定义控件无法在初始化时访问声明的字段

FXML declared custom control can't access declared fields at initialization time

我正在使用 JavaFX/FXML 开发一个控件,然后可以像这样使用它:

<MyControl myNumber="123" />

该控件在首次向用户显示时应该使用 myNumber

问题似乎是在启动时我似乎无法访问 123 的更新值。当 运行 构造函数(预期)时我没有它,但当 运行 Control 的 initialize() 方法时我也没有它。

这是带有一些调试语句的代码:

public class MyControl extends VBox implements Initializable {
    @FXML int myNumber = -1;

    public int getMyNumber() { return myNumber; }

    public void setMyNumber(int myNumber) {
        System.out.println("setMyNumber");
        this.myNumber = myNumber;
    }

    public MyControl() {
        FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myControl.fxml"));
        fxmlLoader.setRoot(this);
        fxmlLoader.setController(this);

        try {
            fxmlLoader.load();
        } catch (IOException exception) {
            throw new RuntimeException(exception);
        }

        System.out.println("constructor = " + myNumber);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        System.out.println("initializable = " + myNumber);
    }
}

打印

initializable = -1
constructor = -1
setMyNumber

如何解决这种情况?

如果你想在 FXML 中使用这个属性,你应该用 @NamedArg 注释声明一个构造函数。

在您的情况下,这将类似于以下示例:

public MyControl(@NamedArg("myNumber") int pMyNumber) {
    myNumber = pMyNumber;
    FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("myControl.fxml"));
    fxmlLoader.setRoot(this);
    fxmlLoader.setController(this);

    try {
        fxmlLoader.load();
    } catch (IOException exception) {
        throw new RuntimeException(exception);
    }
    System.out.println("constructor = " + myNumber);
}