2

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");
    }
}
bunbunn
  • 53
  • 8
  • 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: `` – fabian Jun 05 '17 at 08:20
  • 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 Jun 05 '17 at 12:42
  • At any rate, to call a method on a new controller, use the techniques shown in https://stackoverflow.com/questions/14187963/passing-parameters-javafx-fxml/14190310#14190310 – James_D Jun 05 '17 at 12:42
  • @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 Jun 05 '17 at 15:39
  • 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 Jun 05 '17 at 15:43

1 Answers1

-1

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.

Antoniossss
  • 31,590
  • 6
  • 57
  • 99