Search code examples
javajavafxcontrollerimageviewfxml

Cannot invoke "javafx.scene.image.ImageView.setImage(javafx.scene.image.Image)" because "this.Image1" is null


I am using FXML to make this JavaFX program, and I have run into certain errors I am trying to make the images change after pressing a certain button 3 times, but when I press the button three times it gives me the error of NullPointerException, along with the error message of the title. I suspect that this is because of my main method, where I create a controller to allow for key presses.

Here I initialize the images using a function named createPage, and this is called when initializing the FXML page.

int currentID = 1;
int selected = 1;
int box = currentID%3;
public void createPage() throws URISyntaxException {
        do {
            for (ImageInfo image : Database.ImgList){
                if(image.getId()==currentID){
                    changeImage(image.getName(),box);
                }
            }
            currentID++;
            box = currentID%3;
        } while (box!=1);
    }

This is the main method, where I called a variable for the Controller, which makes it possible to detect key presses and react accordingly, I believe that this is where the problem lies.

public void start(Stage stage) throws IOException {
        HelloController controller = new HelloController();
        Database.loadImages();
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 676, 503);
        scene.setOnKeyPressed(controller::moveCharacter);
        stage.setTitle("For You");
        stage.setScene(scene);
        stage.show();
    }

The two blocks of code below show me trying to detect the certain key press, and after the key is pressed three times, the images will change.

public void moveCharacter(KeyEvent event) {
        switch (event.getCode()){
            case D, RIGHT:
                try {
                    moveForward();
                } catch (URISyntaxException e) {
                    throw new RuntimeException(e);
                }
private void moveForward() throws URISyntaxException {
        if (selected%3==0){
            createPage();
        } else {
            selected++;
        }
    }

When coming across this problem, I tried to check whether using the .setImage function didn't allow me to overwrite the image. This proved to not be the case.

I had also checked the variable, currentID for both functions. This was when I realised that in the moveForward function, the currentID is once again 1. So this led me to believe that something had happened, which turned all the images to null.

I have tried various solutions, such as changing my way of allowing detection of key presses but to no avail.


Solution

  • There isn't really enough information in your question to know for certain what is happening here, but it sounds like HelloController is the controller class specified in your hello-view.fxml, which has an element with fx:id="image1" which is injected into the controller via an @FXML annotation.

    Assuming all this is true, the image1 field will only be initialized in the actual controller, which is an object created for you by the FXMLLoader when the FXML file is loaded and parsed. There is no strange magic by which the image1 fields in other objects will be somehow initialized just because they are of the same class as the actual controller.

    You need to specify the actual controller instance when you register the event handler on the scene, i.e.

    public void start(Stage stage) throws IOException {
        Database.loadImages();
        FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
        Scene scene = new Scene(fxmlLoader.load(), 676, 503);
    
        HelloController controller = fxmlLoader.getController();
    
        scene.setOnKeyPressed(controller::moveCharacter);
        stage.setTitle("For You");
        stage.setScene(scene);
        stage.show();
    }