JavaFX controller is always null

2020-04-30 02:03发布

问题:

I'll try to get in JavaFX 2 and used a simple demo app. The Project consists of 3 Files, the Main.java, the Controller.java and the sample.fxml.

In Sample.fxml i declared the controller:

<GridPane fx:controller="sample.Controller"
      xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
</GridPane>

And in my Main.java I try to access the controller

    FXMLLoader loader = new FXMLLoader();
    Parent root = loader.load(getClass().getResource("sample.fxml"));
    System.out.println(loader.getController()); //prints always null

So my first idea was that the mapping doesn't work. So I added a initialize method in the controller.

@Override
public void initialize(URL url, ResourceBundle resourceBundle) {
    System.out.println("init");
}

The output is now:

init

null

So my Question now is how can i access the controller of a given fxml file?

回答1:

The FXMLLoader.load(URL) method is a static method. So when you execute

  FXMLLoader loader = new FXMLLoader();
  Parent root = loader.load(getClass().getResource("sample.fxml"));

you are not loading the FXML file from the instance of the FXMLLoader that you constructed ("loader"). (You're actually invoking the static method through an object reference.) Hence the loader's controller never gets initialized.

You need

  FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
  Parent root = loader.load();

This constructs a loader with a location specified, and then the load() method, which is not a static method, is properly invoked on the FXMLLoader instance. Then

System.out.println(loader.getController());

will give the correct result.



回答2:

In addition to James_D's answer, I recommend to use the fx:root construct. Then you can inject the custom control (implemented by a controller) in another controller using the @FXML annotation.



标签: java javafx