2017-05-25 68 views
0

假設我有兩個FXML文件:main和帶有自定義組件的文件。我想從定製控制器進入主文件組件,如:如何從不同的文件控制器訪問組件?

Main.fxml:

<FlowPane> 
    <children> 
     <TextField fx:id="source" /> 
     <CustomBox fx:id="cbox" /> 
    </children> 
</FlowPane> 

Custom.fxml:

<fx:root type="HBox"> 
    <children> 
     <Button fx:id="showButton" onAction="#show" text="Show" /> 
    </children> 
</fx:root> 

CustomBox.java:

public class CustomBox extends HBox { 
    @FXML 
    private TextField source; 

    public CustomBox() { 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("Custom.fxml")); 
     loader.setRoot(this); 
     loader.setController(this); 
     try { 
      loader.load(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    @FXML 
    protected void show() { 
     System.out.println(source.getText()); 
    } 
} 

但方法show()給我NPE。我如何從不同的文件綁定組件和控制器?

+0

你不能注入中定義的控制一個FXML文件放到另一個FXML文件的控制器中 - 一般來說,在控制器之外爲其定義的FXML公開控件是一種不好的做法。相反,將對主控制器的引用傳遞給自定義組件,並調用主控制器上的方法來檢索文本(或使用MVC方法並定義模型類,並與兩個控制器共享模型的實例)。 –

回答

0

您可以定義主FXML文件控制器,並公開從它的文字:

public class MainController { 

    @FXML 
    private TextField source ; 

    @FXML 
    private CustomBox cbox ; 

    public String getText() { 
     return source.getText(); 
    } 

    @FXML 
    protected void initialize() { 
     cbox.setMainController(this); 
    } 
} 

當然並將其指定爲控制器類中Main.fxml文件

<FlowPane fx:controller="my.package.MainController"> 
    <children> 
     <TextField fx:id="source" /> 
     <CustomBox fx:id="cbox" /> 
    </children> 
</FlowPane> 

然後修改您的CustomBox

public class CustomBox extends HBox { 

    private MainController mainController ; 

    public CustomBox() { 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("Custom.fxml")); 
     loader.setRoot(this); 
     loader.setController(this); 
     try { 
      loader.load(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public void setMainController(MainController mainController) { 
     this.mainController = mainController ; 
    } 

    public MainController getMainController() { 
     return mainController ; 
    } 

    @FXML 
    protected void show() { 
     System.out.println(mainController.getText()); 
    } 
} 

我還沒有teste d,但你可能只是能夠指定在FXML文件中的主控制器:

<FlowPane fx:controller="my.package.MainController"> 
    <children> 
     <TextField fx:id="source" /> 
     <CustomBox fx:id="cbox" mainController="$controller" /> 
    </children> 
</FlowPane> 

,然後忽略在MainControllerinitialize()方法:

public class MainController { 

    @FXML 
    private TextField source ; 

    public String getText() { 
     return source.getText(); 
    } 

} 
+0

謝謝,我明白了。 –