user3424455
user3424455

Reputation: 105

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.

Upvotes: 1

Views: 2451

Answers (2)

Nyla of Arda
Nyla of Arda

Reputation: 106

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();
}

}

Upvotes: 0

Lealo
Lealo

Reputation: 321

You need 2 stages to do what you want (not only 2 scenes).

Stage st
st.setOnCloseRequest(e -> {

});

Will allow to preform any code you want when your stage closes (your newWindow).

Then you use getText() on your TextField object - and setText() onto your main stage Label object.

st.initModality(Modality.APPLICATION_MODAL);

...Will make it modal.

Upvotes: 1

Related Questions