JavaFX控制器注入不起作用

时间:2015-09-29 16:33:03

标签: javafx fxml

我有两个fxml个文件。我用include语句连接它们:

“main”fxml文件看起来像这样:     

<?import javafx.geometry.*?>
// ...

<BorderPane prefHeight="962" prefWidth="1280" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MyMainController">
    <center>
        <SplitPane dividerPositions="0.63" BorderPane.alignment="CENTER">
            <items>
                <fx:include source="AnotherFile.fxml" />
                // ...
            </items>
        </SplitPane>
    </center>
    <top>
        // ...
    </top>
</BorderPane>

第二个(=“AnotherFile.fxml”)是这样的:     

<?import java.lang.*?>
// ...

<SplitPane dividerPositions="0.15" orientation="VERTICAL" prefHeight="400.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
    <items>
        // ...
        <Label fx:id="oneOfMyLabels" text="myText" GridPane.columnIndex="2" GridPane.rowIndex="1" />
    </items>
</SplitPane>

现在,我在“主要”控制器application.MyMainController中使用注射:

@FXML
private Label oneOfMyLabels;

如果我运行控制器,我会得到一个java.lang.NullPointerException异常,分别是java.lang.reflect.InvocationTargetException异常。在调试模式中,我发现注入的Labelnull

现在,我的问题: 无法从“主要fxml文件”到达MyMainController所包含的fxml文件的组件?我是否必须在每个fxml文件上使用自己的控制器,如果包含或不包含?!

感谢您的帮助!!

1 个答案:

答案 0 :(得分:4)

每个FXML文件需要一个不同的控制器,每个文件的fx:id - 注释元素将被注入对应的控制器实例。

当您包含FXML文件时,您可以通过在fx:id元素上设置fx:include属性,将包含文件的控制器注入到包含文件的控制器中:

“main”fxml文件:

<?import javafx.geometry.*?>
// ...

<BorderPane prefHeight="962" prefWidth="1280" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MyMainController">
    <center>
        <SplitPane dividerPositions="0.63" BorderPane.alignment="CENTER">
            <items>
                <fx:include fx:id="another" source="AnotherFile.fxml" />
                // ...
            </items>
        </SplitPane>
    </center>
    <top>
        // ...
    </top>
</BorderPane>

并在“主控制器”中:

public class MyMainController {

    @FXML
    private AnotherController anotherController ;

    // ...
}

(规则是字段名称是附加fx:id的{​​{1}}属性的值。这里"Controller"AnotherController的控制器类。

现在,您可以在“包含的控制器”中公开您需要访问的数据

AnotherFile.fxml

然后您的主控制器可以执行

之类的操作
public class AnotherController {

    @FXML
    private Label oneOfMyLabels ;

    public StringProperty textProperty() {
        return oneOfMyLabels.textProperty();
    }

    public final String getText() {
        return textProperty().get();
    }

    public final setText(String text) {
        textProperty().set(text);
    }

    // ...
}

当然会更新标签。这样可以保留封装,因此如果您选择使用其他控件而不是标签,则这些更改不必在直接控制器之外传播。