JavaFX 控制器注入不起作用
JavaFX controller injection does not work
我有两个 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>
现在,我在 "main"-控制器中使用注入 application.MyMainController
:
@FXML
private Label oneOfMyLabels;
如果我 运行 控制器我得到一个 java.lang.NullPointerException
异常,分别是 java.lang.reflect.InvocationTargetException
一个。在调试模式下,我发现注入的 Label
是 null
!
现在,我的问题是:
无法从包含的 fxml 文件的 "main fxml file" 组件到达 MyMainController
?我是否必须在每个 fxml 文件上使用自己的控制器,无论是否包含?!
感谢您的帮助!!
您需要为每个 FXML 文件设置不同的控制器,并且每个文件的 fx:id
-注释元素将被注入到 对应的 控制器实例中。
包含 FXML 文件后,可以通过在 fx:include
元素上设置 fx:id
属性,将包含文件的控制器注入到包含文件的控制器中:
"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>
并在 "main controller" 中:
public class MyMainController {
@FXML
private AnotherController anotherController ;
// ...
}
(规则是字段名称是附加了 "Controller"
的 fx:id
属性的值)。这里 AnotherController
是 AnotherFile.fxml
的控制器 class。
例如,现在您可以在 "included controller":
中公开您需要访问的 数据
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);
}
// ...
}
然后你的主控制器可以做类似
的事情
anotherController.setText(...);
这当然会更新标签。这保留了封装,因此如果您选择使用另一个控件而不是标签,则这些更改不必传播到直接控制器之外。
我有两个 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>
现在,我在 "main"-控制器中使用注入 application.MyMainController
:
@FXML
private Label oneOfMyLabels;
如果我 运行 控制器我得到一个 java.lang.NullPointerException
异常,分别是 java.lang.reflect.InvocationTargetException
一个。在调试模式下,我发现注入的 Label
是 null
!
现在,我的问题是:
无法从包含的 fxml 文件的 "main fxml file" 组件到达 MyMainController
?我是否必须在每个 fxml 文件上使用自己的控制器,无论是否包含?!
感谢您的帮助!!
您需要为每个 FXML 文件设置不同的控制器,并且每个文件的 fx:id
-注释元素将被注入到 对应的 控制器实例中。
包含 FXML 文件后,可以通过在 fx:include
元素上设置 fx:id
属性,将包含文件的控制器注入到包含文件的控制器中:
"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>
并在 "main controller" 中:
public class MyMainController {
@FXML
private AnotherController anotherController ;
// ...
}
(规则是字段名称是附加了 "Controller"
的 fx:id
属性的值)。这里 AnotherController
是 AnotherFile.fxml
的控制器 class。
例如,现在您可以在 "included controller":
中公开您需要访问的 数据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);
}
// ...
}
然后你的主控制器可以做类似
的事情anotherController.setText(...);
这当然会更新标签。这保留了封装,因此如果您选择使用另一个控件而不是标签,则这些更改不必传播到直接控制器之外。