Search code examples
javafxnullpointerexceptionfxml

JavaFX fx:id doesn´t create a Object in the controller class


Hello I am new to JavaFX and have problems with the fx:id.

I get a null pointer exception in my controller class.

The objects apple and snake are not created, although the fx:id and declarations in the controller class match.

Can someone help me?

Main-Class:

public class Main extends Application {


    private Controller controll = new Controller();

    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("World2.fxml"));
            Scene scene = new Scene(root);
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            scene.setOnKeyPressed(controll);
            primaryStage.setScene(scene);

            primaryStage.show();


        } catch(Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }


}

Controller-Class:

public class Controller implements EventHandler<Event> {

    @FXML
    private ImageView snake;
    @FXML
    private ImageView apple;

    private int snakeRow = 8;
    private int snakeColumn = 10;
    private int appleRow = 5;
    private int appleColumn = 5;

    @Override
    public void handle(Event ev) {

        KeyEvent event = (KeyEvent) ev;

        System.out.println("handle-Methode");

        if (event.getCode() == KeyCode.LEFT && snakeColumn > 0) {
            snakeColumn--;

            System.out.println("Snake-ID: " + snake);
            System.out.println("Apple-ID: " + apple);

        }
    }

FXML:

   <ImageView fx:id="apple" fitHeight="39.0" fitWidth="44.0" pickOnBounds="true" GridPane.columnIndex="5" GridPane.rowIndex="5">
         <image>
            <Image url="@../img/icons8-apfel-48.png" />
         </image>
     </ImageView>
    <ImageView fx:id="snake" fitHeight="36.0" fitWidth="44.0" pickOnBounds="true" GridPane.columnIndex="10" GridPane.rowIndex="8">
       <image>
          <Image url="@../img/icons8-hydra-48.png" />
       </image>
    </ImageView>

Solution

  • A controller instance is not associated with a scene unless

    1. It's created by FXMLLoader based on the fx:controller attribute in the fxml. In this case you'd need to retrieve the controller instance from the FXMLLoader instance used to load the fxml after loading:

      FXMLLoader loader = new FXMLLoader(getClass().getResource("World2.fxml"));
      Parent root = loader.load();
      Controller controll = loader.getController();
      

      or

    2. You don't specify the fx:controller attribute but pass a Object to FXMLLoader before loading that is to be used as controller for the scene:

      FXMLLoader loader = new FXMLLoader(getClass().getResource("World2.fxml"));
      loader.setController(controll);
      Parent root = loader.load();