Nik
Nik

Reputation: 179

JavaFX - setText() is not working

I cant set the text of a Textfield. There is no error but the Textfield is still empty. The rest of the program is working, the method is called and the System.out.println(...) prints the right text. So the problem is, the text of the textfield cant be set. Even if i just write textField.setText("0"); the textfield is still empty. When I set the text for the textfield under public void initialize(...) it also works. So why doesn't it work in setCurrentInfo?

@FXML
private TextField textField;

private Info currentInfo;

 @Override
public void initialize(URL url, ResourceBundle rb) {
}   

public void setCurrentInfo(Info currentInfo) {
    textField.setText(currentInfo.getpw1());
    System.out.println(currentInfo.getpw1());
    this.currentInfo = currentInfo;
}

The part of the controller where setCurrentInfo is called:

@FXML
private void handleBtn1(ActionEvent event) throws Exception{
    Info info = new Info(textFieldA.getText(), textFieldB.getText());
    FXMLLoader loader = new FXMLLoader();
    loader.setLocation(getClass().getResource("FXMLPassword.fxml"));
    loader.load();
    Stage stage; 
    Parent root;
    if(event.getSource()==btn1){
        //get reference to the button's stage         
        stage=(Stage) btn1.getScene().getWindow();
        //load up OTHER FXML document
        root = FXMLLoader.load(getClass().getResource("FXMLPassword.fxml"));
    }
    else{
        stage=(Stage) btn1.getScene().getWindow();
        root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    }
    //create a new scene with root and set the stage
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
    FXMLPasswordController passwordController = loader.getController();
    passwordController.setCurrentInfo(info);
    }

Upvotes: 5

Views: 10545

Answers (1)

James_D
James_D

Reputation: 209330

You are retrieving the controller from the wrong FXMLLoader. In particular, you do:

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("FXMLPassword.fxml"));
loader.load();

and then later

FXMLPasswordController passwordController = loader.getController();

In this code, you create an FXMLLoader and point it to the FXMLPassword.fxml file. But when you call loader.load(), which reads the fxml file and creates the UI defined in it, you do nothing with the result. So the UI created by that call to loader.load() is never displayed.

Consequently, when you get the controller from that loader, and use it to make changes to the UI, you will never see those changes because that instance of the TextField is not displayed.

The TextField that is displayed is created when you call

root = FXMLLoader.load(getClass().getResource("FXMLPassword.fxml"));

but since you use the static version of the FXMLLoader.load(...) method here, you have no opportunity to get the controller associated with it.

You need to refactor the code as follows:

@FXML
private void handleBtn1(ActionEvent event) throws Exception{
    Info info = new Info(textFieldA.getText(), textFieldB.getText());
    Stage stage; 
    Parent root;
    if(event.getSource()==btn1){
        //get reference to the button's stage         
        stage=(Stage) btn1.getScene().getWindow();
        //load up OTHER FXML document
        FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("FXMLPassword.fxml"));
        root = loader.load();
        FXMLPasswordController passwordController = loader.getController();
        passwordController.setCurrentInfo(info);
    }
    else{
        stage=(Stage) btn1.getScene().getWindow();
        root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
    }
    //create a new scene with root and set the stage
    Scene scene = new Scene(root);
    stage.setScene(scene);
    stage.show();
}

Upvotes: 4

Related Questions