2015-09-04 125 views
0

在我的GUI应用程序中,我有两个视图:playlistView.fxmlvideoView.fxml。每个都有自己的控制器。我想playListViewvideoView布局的一部分,所以我用:JavaFX8 FXML控制器注入

<fx:include fx:id="idPlayListAnchorPane" source="playListView.fxml" /> 

包含的文件。工作正常,播放列表显示为videoView布局的一部分。

然后我注入idPlayListAnchorPane FXML可变进VideoViewController这样的:

@FXML 
private AnchorPane idPlayListAnchorPane;  

工作过。例如,我可以在playListViewVideoViewController与禁用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中。几个小时后的简单问题是:为什么不呢?从<fx:include>一次,一次,当你在代码中创建FXMLLoader并调用load()

+0

经过一番调查后,我发现ListView中的onAction处理程序不再触发,所以显然在listview控制器和videoViewController之间没有“连接”。我认为我最好的选择是fx:include,但忘记了一个单独的控制器并将代码粘贴到第一个控制器中。 – Frank

+0

不要这样做。你仍然会有两个控制器,他们只会来自同一个班级。除了仍然存在如何在两个控制器实例之间进行通信的问题之外,要跟踪每个实例中哪些字段已初始化将非常困难。 (其中一个将从一个FXML初始化,另一个来自另一个FXML)。只需使用[documentation](http://docs.oracle.com/javase/8/javafx/api/javafx/fxml)中显示的标准机制/doc-files/introduction_to_fxml.html#nested_controllers) –

回答

4

正在加载的文件playListView.fxml两次。在您的GUI中显示由<fx:include>创建的节点层次结构(即AnchorPane及其所有内容)由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 -annotated场注入控制器直接进入VideoViewController类称为idPlayListAnchorPaneController(该规则是追加“控制器”来该编号):

public class VideoViewController { 
    @FXML 
    private AnchorPane idPlayListAnchorPane; 
    @FXML 
    private PlayListViewController idPlayListAnchorPaneController ; 

    // ... 
} 

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

+0

是的!谢谢詹姆斯。我在“Pro JavaFX8”一书中找到了一个示例,并尝试了FXML注入,但无法使其正常工作。我微弱的尝试和你工作的版本之间的细微差别是,我用私人PlayListViewController playListViewController,它应该已经私人PlayListViewController idPlayListAnchorPaneController。由于JavafX Oracle,事情变得更加清晰了;-) – Frank