JavaFX8 FXML 控制器注入
JavaFX8 FXML Controller injection
在我的 GUI 应用程序中,我有两个视图:playlistView.fxml 和 videoView.fxml。每个都有自己的控制器。我希望 playListView 成为 videoView 布局的一部分,所以我使用:
<fx:include fx:id="idPlayListAnchorPane" source="playListView.fxml" />
包含文件。工作正常,播放列表显示为 videoView 布局的一部分。
然后我将 idPlayListAnchorPane FXML 变量注入到 VideoViewController 中,如下所示:
@FXML
private AnchorPane idPlayListAnchorPane;
也可以。例如,我可以从 VideoViewController 中禁用 playListView 中的 idPlayListAnchorPane:
idPlayListAnchorPane.setDisable(true);
要获取我使用的 playListViewController:
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/designer/views/video/playListView.fxml"));
PlayListViewController playListViewController = new PlayListViewController();
loader.setController(playListViewController);
try {
AnchorPane playListView = (AnchorPane) loader.load();
} catch (IOException e) {
};
然后我可以调用例如:
playListViewController.init();
来自 videoView控制器。
但是 init() 方法在 playListView ListView 中创建了一些测试值(作为单独的应用程序测试并且有效)。但是,这些测试值现在不会显示在 ListView 中。许多小时后的简单问题是:为什么不呢?
您正在加载 playListView.fxml
文件两次:一次从 <fx:include>
加载,一次是在代码中创建 FXMLLoader
并调用 load()
。由 <fx:include>
创建的节点层次结构(即 AnchorPane
及其所有内容)显示在您的 GUI 中; FXMLLoader.load()
调用创建的不是。
由于您创建的控制器与未显示的节点层次结构相关联,因此您在控制器上调用的方法将不会影响您的 UI。
无需创建 FXMLLoader
来获取控制器实例,您可以使用文档中描述的 Nested Controller 技术将包含的 FXML 中的控制器直接注入到您的 VideoViewController
中。
为此,首先将 fx:controller
属性添加到 playListView.fxml
根元素:
playListView.fxml:
<!-- imports etc -->
<AnchorPane fx:controller="com.mycompany.packagename.PlayListViewController">
<!-- etc etc -->
</AnchorPane>
因为您在 <fx:include ...>
上定义了 fx:id="idPlayListAnchorPane"
属性,您可以使用 @FXML
将控制器直接注入 VideoViewController
class - 名为 idPlayListAnchorPaneController
的注释字段(规则是将 "Controller" 附加到 id):
public class VideoViewController {
@FXML
private AnchorPane idPlayListAnchorPane;
@FXML
private PlayListViewController idPlayListAnchorPaneController ;
// ...
}
现在您可以根据需要调用控制器上的方法。
在我的 GUI 应用程序中,我有两个视图:playlistView.fxml 和 videoView.fxml。每个都有自己的控制器。我希望 playListView 成为 videoView 布局的一部分,所以我使用:
<fx:include fx:id="idPlayListAnchorPane" source="playListView.fxml" />
包含文件。工作正常,播放列表显示为 videoView 布局的一部分。
然后我将 idPlayListAnchorPane FXML 变量注入到 VideoViewController 中,如下所示:
@FXML
private AnchorPane idPlayListAnchorPane;
也可以。例如,我可以从 VideoViewController 中禁用 playListView 中的 idPlayListAnchorPane:
idPlayListAnchorPane.setDisable(true);
要获取我使用的 playListViewController:
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/designer/views/video/playListView.fxml"));
PlayListViewController playListViewController = new PlayListViewController();
loader.setController(playListViewController);
try {
AnchorPane playListView = (AnchorPane) loader.load();
} catch (IOException e) {
};
然后我可以调用例如:
playListViewController.init();
来自 videoView控制器。
但是 init() 方法在 playListView ListView 中创建了一些测试值(作为单独的应用程序测试并且有效)。但是,这些测试值现在不会显示在 ListView 中。许多小时后的简单问题是:为什么不呢?
您正在加载 playListView.fxml
文件两次:一次从 <fx:include>
加载,一次是在代码中创建 FXMLLoader
并调用 load()
。由 <fx:include>
创建的节点层次结构(即 AnchorPane
及其所有内容)显示在您的 GUI 中; FXMLLoader.load()
调用创建的不是。
由于您创建的控制器与未显示的节点层次结构相关联,因此您在控制器上调用的方法将不会影响您的 UI。
无需创建 FXMLLoader
来获取控制器实例,您可以使用文档中描述的 Nested Controller 技术将包含的 FXML 中的控制器直接注入到您的 VideoViewController
中。
为此,首先将 fx:controller
属性添加到 playListView.fxml
根元素:
playListView.fxml:
<!-- imports etc -->
<AnchorPane fx:controller="com.mycompany.packagename.PlayListViewController">
<!-- etc etc -->
</AnchorPane>
因为您在 <fx:include ...>
上定义了 fx:id="idPlayListAnchorPane"
属性,您可以使用 @FXML
将控制器直接注入 VideoViewController
class - 名为 idPlayListAnchorPaneController
的注释字段(规则是将 "Controller" 附加到 id):
public class VideoViewController {
@FXML
private AnchorPane idPlayListAnchorPane;
@FXML
private PlayListViewController idPlayListAnchorPaneController ;
// ...
}
现在您可以根据需要调用控制器上的方法。