Search code examples
javajavafxfxml

Getting access to ui elements in different fxml file


I have a FXML-application with a main.fxml, which includes two other fxml files. Each of these fxml files has its own controller class.

My question is, of how to get access to objects from a specific controller, although these objects are defined on another fxml file.

The following code is just a minimal example. I thought it was a good idea to split ui elements in different fxml files, because they are getting larger and larger.

My main fxml:

<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="MainController">
   <fx:include fx:id="top" source="top.fxml"/>
   <fx:include fx:id="bottom" source="bottom.fxml"/>
</VBox>

top.fxml:

<VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="ControllerTop">
  <children>
    <Button fx:id="topbtn" onAction="#printOutput" text="OK" />
  </children>
</VBox>

bottom.fxml

<VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="ControllerBottom">
  <children>
    <Button fx:id="bottombtn" onAction="#printOutput" text="OK" />
  </children>
</VBox>

For top.fxml i have created this controller class:

public class ControllerTop {
    @FXML public Button topbtn;
    @FXML public Button bottombtn;

    @FXML
    public void printOutput() {
        System.out.println("Hello from top button");
        topbtn.setDisable(true); //OK!
        bottombtn.setDisable(false); //Failed
    }
}

Of course bottombtn is defined in bottom.fxml and has its own controller. The problem is, that bottombtn of printOut() of this ControllerTop results in a NullPointerException. So i need help by accessing objects in a nice and smart way.

Thanks


Solution

  • in main controller:

    public class MainController {
    /**
     * var name has to be topController
     */
    public TopController topController;
    /**
     * var name has to be bottomController
     */
    public BottomController bottomController;
    
    public void initialize(){
        Button topbtn=topController.topbtn;
        Button bottombtn=bottomController.bottombtn;
        topbtn.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                System.out.println("Hello from top button");
                topbtn.setDisable(true); //OK!
                bottombtn.setDisable(false); //Failed
            }
        });
    
    }
    }
    

    bottom.fxml:

        <VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="BottomController">
      <children>
        <Button fx:id="bottombtn" text="OK" />
      </children>
    </VBox>
    

    top.fxml:

     <VBox fx:id="vbox" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="TopController">
      <children>
        <Button fx:id="topbtn" text="OK" />
      </children>
    </VBox>
    

    and in class TopController and BottomController set @FXML public Button **btnName**;

    BottomController:

    public class BottomController {    
        public Button bottombtn;
    }
    

    TopController:

    public class TopController {
        public Button topbtn;
    }
    

    Another option it to use initialize at MainController to set the value of bottombtn in topController