JavaFX8 FXML控制器注入

时间:2015-09-04 22:58:11

标签: controller javafx-8 fxml

在我的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();    
来自 videoViewController

但init()方法在 playListView ListView中创建了一些测试值(作为单独的应用程序进行测试,并且可以正常工作)。但是,这些测试值现在不会显示在ListView中。几个小时后的简单问题是:为什么不呢?

1 个答案:

答案 0 :(得分:5)

您要加载playListView.fxml文件两次:一次来自<fx:include>,一次是在代码中创建FXMLLoader并致电load()。由AnchorPane创建的节点层次结构(即<fx:include>及其所有内容)显示在GUI中;由FXMLLoader.load()调用创建的那个不是。

由于您创建的控制器与未显示的节点层次结构相关联,因此您在控制器上调用的方法将不会对您的UI产生任何影响。

您可以使用文档中描述的Nested Controller技术将包含FXML的控制器直接注入您的FXMLLoader,而不是创建VideoViewController来获取控制器实例。

为此,请先向fx:controller根元素添加playListView.fxml属性:

playListView.fxml:

<!-- imports etc -->
<AnchorPane fx:controller="com.mycompany.packagename.PlayListViewController">
    <!-- etc etc -->
</AnchorPane>

由于您在fx:id="idPlayListAnchorPane"上定义了<fx:include ...>属性,因此可以使用名为{{VideoViewController的带注释字段将控制器直接注入@FXML类1}}(规则是你将“Controller”附加到id):

idPlayListAnchorPaneController

现在您可以根据需要调用控制器上的方法。