JavaFX, Label null pointer exception
I am having the following problem with a program that I am currently writing, and I have searched on the internet, but I couldn't really find anything to help me understand the following problem
So inside another class I have written a method that executes this whenever the search button is clicked and the method looks like this:
public void searchButton(){
try {
new SearchController().display();
} catch (IOException e) {
e.printStackTrace();
}
}
And then the SearchController class looks something like this (I simplified it here):
public class SearchController {
@FXML
private Button cancelButton;
@FXML
private Label what;
private static Stage stage;
private static BorderPane borderPane;
@FXML
public void initialize(){
what.setText("Testing"); // this woks
cancelButton.setOnAction(e -> stage.close());
}
public void display() throws IOException {
stage = new Stage();
stage.setResizable(false);
stage.setTitle("Product search");
stage.initModality(Modality.APPLICATION_MODAL);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(SearchController.class.getResource("Search.fxml"));
borderPane = loader.load();
Scene scene = new Scene(borderPane);
stage.setScene(scene);
//what.setText("Testing") and this doesn't work
stage.showAndWait();
}
}
Can someone please tell me why it is possible to write text on the initialize method (that method gets called after the borderPane = loader.load();
line...so why doesn't it work if I try to write on the label after that line?)
Thank you in advance
The FXMLLoader
creates an instance of the class specified in the fx:controller
attribute of the FXML root element. It then injects the elements defined in the FXML file into the controller instance it created when the fx:id
attributes match the field names. Then it calls the initialize()
method on that instance.
You create an instance of the controller "by hand" with new SearchController()
. This is not the same object that is created by the FXMLLoader
. So now when you have loaded the fxml file you have two different instances of SearchController
. So if you call what.setText(...)
from the display()
method, you are not calling it on the controller instance created by the FXMLLoader
. Consequently, what
has not been initialized in the instance on which you are calling what.setText(...)
, and you get a null pointer exception.
Since initialize()
is invoked by the FXMLLoader
on the instance it created, when you call what.setText(...)
from the initialize()
method, you are calling it on the instance created by the FXMLLoader
, and so the FXML-injected fields for that instance have been initialized.