Search code examples
javafxscenestage

javaFX - how to use function or object of a controller from another controller


I have seen a lot of question similar to mine, but I didn't figure it out how to solve my problem, so there is my code:

I have a simple main:

MainClassFXGui.java

public class MainClassFXGui extends Application {

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));

        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Assicurazione");
        stage.show();
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

and three fxml files, one of them that contains the other two, by the tag

<fx:include source="MyTab1.fxml" />

MyProgramMainGuiTab.fxml

...
<TabPane maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" prefHeight="5000.0" prefWidth="5000.0" tabClosingPolicy="UNAVAILABLE">
          <tabs>
              <Tab closable="false" text="MyTab1">
                   <content>
    <fx:include source="MyTab1.fxml" />
                   </content>
              </Tab>
              <Tab closable="false" text="MyTab2">
                   <content>
    <fx:include source="MyTab2.fxml" />
                   </content>
              </Tab>
          </tabs>
    </TabPane>
...

and three controller:

MyProgramMainGuiTabController.java

....
@FXML
private Label LeftSt;
/**
 * Initializes the controller class.
 */
@Override
public void initialize(URL url, ResourceBundle rb) {
    LeftSt.setText("");
}    

public void setLeftSt(String st){
    LeftSt.setText(st);
}
...

MyTab1Controller.java

@FXML
private void handleButtonAction(ActionEvent event) {
    System.out.println("You clicked me!");
    setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}

I tried in this way:

MyTab1Controller.java

private MyProgramMainGuiTabController controller;

@FXML
private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");
        controller.setLeftSt("Can I change the label of the MyProgramMainGuiTabController?");
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    FXMLLoader fxmlLoader = new
    FXMLLoader(getClass().getResource("MyProgramMainGuiTab.fxml"));
    try {
         fxmlLoader.load();            
    } catch (IOException exception) {
         throw new RuntimeException(exception);
    }
    controller = (MyProgramMainGuiTabController)fxmlLoader.getController();
}

But I have a null pointer exception or if I move the code for the instanzialization of the object 'controller' in the handleButtonAction function, I don't have any error, but the label does not change.

Maybe I can create a static Scene and a static Stage in the MainClassFXGui.java? but then I don't know how I could use them...

MainClassFXGui.java

public class MainClassFXGui extends Application {
    static private Scene scene;
    static private Stage stage;

    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("MyProgramMainGuiTab.fxml"));

        this.scene = new Scene(root);
        stage.setScene(scene);
        stage.setTitle("Assicurazione");
        stage.show();
        this.stage = stage;
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }

    public static Scene getScene(){
        return AssicurazioneFXGui.scene;
    }

    public static Stage getStage(){
        return AssicurazioneFXGui.stage;
    }

}

can I do something with getScene() or getStage()? any idea or suggest?

thanks to everyone


Solution

  • At the moment I have solved in this way. If anyway someone has a better solution, please write. Also because this does not solve the problem if I need to execute a function.. thanks

    MyProgramMainGuiTabController.fxml

    ...
    @FXML
    private Label LeftSt;
    /**
     * Initializes the controller class.
     */
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        LeftSt.setText("");
    }  
    ...
    

    MyTab1Controller.fxml

    @FXML
    private Button myObject;
    
    private Scene scene;
    private Label lblDataLeft;
    
    @FXML
    private void handleButtonAction(ActionEvent event) {
            System.out.println("You clicked me!");
            setLeftSt("this works!");
    }
    
    public void setLeftSt(String st){
        if(this.scene == null)
            this.scene = myObject.getScene();
        if(this.lblDataLeft==null)
            this.lblDataLeft = (Label) scene.lookup("#LeftSt");
        if (this.lblDataLeft!=null) 
            this.lblDataLeft.setText(st); 
    }