2015-09-04 124 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