Search code examples
javajavafxfxml

JavaFX and FXML - update label with data from another controller


I have one window with a Label and a Button, and another window with a TextField and a Button. From the main window I want to open the other window using the button, enter something in the text field on the new window, and after clicking the button on the new window I want it to close and the main window label to update with the text that was entered. Also I want the new window to be modal.

Main Window

New Window

public class MainController {

    @FXML
    public void showNewWindow() {
        try {
            Stage newWindowStage = new Stage();
            newWindowStage.setTitle("New Window");
            newWindowStage.initModality(Modality.APPLICATION_MODAL);
            VBox root = FXMLLoader.load(getClass().getResource("newWindow.fxml"));
            Scene scene = new Scene(root);
            newWindowStage.setScene(scene);
            newWindowStage.showAndWait();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


public class NewWindowController {

    @FXML
    private TextField textField;

    @FXML
    public void updateMainWindowLabel() {
        // update label in main window
        // close new window
    }
}

I know it's not set up right at all but hopefully it explains what I'm trying to do.


Solution

  • Here is example code that works (It isn't the neatest so I would appreciate edits)

    I don't have a full understanding of Modal windows but here I found another question related to that.

    Main Class that extends Application:

    public static void main(String[] args) {
        Application.launch(Test.class, args);
    }
    
    private static Stage stage1;
    private static Stage stage2;    
    private static MyExampleController controller;
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        stage1 = primaryStage;        
        FXMLLoader loader1 = new FXMLLoader(Test.class.getResource("/test/MyExample.fxml"));
        AnchorPane pane1 = (AnchorPane)loader1.load();
        controller = loader1.getController();
        Scene scene1 = new Scene(pane1);
        stage1.setScene(scene1);
        
        stage2 = new Stage();
        FXMLLoader loader2 = new FXMLLoader(Test.class.getResource("/test/MyEx2.fxml"));
        AnchorPane pane2 = (AnchorPane)loader2.load();
        Scene scene2 = new Scene(pane2);
        stage2.setScene(scene2);
        
        stage1.show();
    }
      
    public static Stage getStage2(){
        return stage2;
    }
    
    public static MyExampleController getController(){
        return controller;
    }
    

    Controller class 1:

    public class MyExampleController implements Initializable {
    
    @FXML
    private Label labLab;
    @FXML
    private Button btnButton;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {       
    }    
    
    @FXML
    private void clickButton(ActionEvent event) {
        Test.getStage2().show();
    }
    
    public void updateLabel(String newLabelText){
       this.labLab.setText(newLabelText);
    }
    }
    

    Controller class 2:

    public class MyEx2Controller implements Initializable {
    
    @FXML
    private Button btnUpdate;
    @FXML
    private TextField txtField;
    
    @Override
    public void initialize(URL url, ResourceBundle rb) {
    }    
    
    @FXML
    private void doUpdateForTitle(ActionEvent event) {
        Test.getController().updateLabel(txtField.getText());
        Test.getStage2().close();
    }
    
    }