2
votes

I'm trying to set a TextField's value when the respective FXML file is loaded, but when I tried to set a default value on the TextField in the method where the FXML is loaded, in this case in the writeBtnClick() method, it throws a NullPointerException.

To my understanding, an element is not initialized until the FXML is loaded, so for whatever reason after loading the FXML file, the element is still not recognized.

Controller.java

public class Controller implements Initializable {
    @FXML private TextField textField;

    public void initialize(URL arg0, ResourceBundle arg1) {

    }

    public void writeBtnClick(ActionEvent event) throws IOException {
        Stage stage = (Stage) ((Node)event.getSource()).getScene().getWindow();
        stage.setScene(new Scene((Parent) FXMLLoader.load(getClass().getResource("WriteScene.fxml"))));

        // the textfield I'm trying to set default value on
        // this throws a NullPointerException
        textField.setText("name");
    }

To circumvent this problem I put the setText() in initialize() but of course that would also result in NullPointerException if the controller class gets called before loading the correct fxml file.

This is the best way I could come up with but obviously it's very dirty and I feel like there should be a way to set the value on the writeBtnClick() method where the scene actually gets loaded.

public void initialize(URL arg0, ResourceBundle arg1) {
    // very hacky solution
    if (textField != null) {
        textField.setText("name");
    }
}
1
Simply do not use the Controller class for fxmls not containing a TextField with a fx:id of textField. You do need to make sure similar requirements are met anyway. E.g. this element in a fxml would result in a exception when loading it with your controller class too: <Button fx:id="textField"/> - fabian
It sounds like you are using the same controller class for two (or more) different FXML files. Don't do this: it is too confusing. You won't be able to keep track of which instances of the controller class have which fields initialized and which ones still null. Create a different controller class for each FXML file. - James_D
At any rate, to call a method on a new controller, use the techniques shown in stackoverflow.com/questions/14187963/… - James_D
@James_D oh so that's why, I had an erroneous assumption that you can use the controller as a class to control the whole thing. That makes sense, but now it feels like I'd have too many files for a simple program. - bunbunn
Well you could just use one class, but as I said it gets more confusing. You still have to remember that you would have multiple instances of that controller class. In the long run, more classes with specific responsibilities will be easier to maintain. - James_D

1 Answers

-1
votes

I know it can sound crazy, but remove implements Initializable from your controller definition, but leave initialize method. Ther will be no NPE anymore.

In case you will still get some NPE on GUI element, double check @fx:id tags, as there is most probably a typo (case sensitive), and inflator will not complain about it.