fmatt
fmatt

Reputation: 494

why is ImageView reference null when I get it using id?

I put an image o my fxml file, give an id to it and then use the id in relevant controller. but I don't understand why it is null??

here is my fxml file :

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.Pane?>

<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.Ball">
   <children>
         <ImageView fx:id="imageView" fitHeight="150.0" fitWidth="200.0" layoutX="153.0" layoutY="116.0" pickOnBounds="true" preserveRatio="true">
            <image>
               <Image url="@../resources/2.jpg" />
            </image>
         </ImageView>
   </children>
</Pane>

and this is the controller class :

package sample;

import javafx.fxml.FXML;
import javafx.scene.image.ImageView;
import javafx.scene.input.KeyEvent;

import static javafx.scene.input.KeyCode.UP;

public class Ball {
    @FXML
    public ImageView imageView;

    public void moveBallOnKeyPress(KeyEvent e) {
        if (e.getCode().equals(UP)) {
            System.out.println(imageView);
        }
    }
}

and here is how I call this method :

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class Main extends Application {
public static Scene scene ;

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
        primaryStage.setTitle("Hello World!");
        scene = new Scene(root, 600, 550);
        Ball ball = new Ball();
        scene.setOnKeyPressed(e -> ball.moveBallOnKeyPress(e));
        primaryStage.setScene(scene);
        primaryStage.show();
    }


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

what I see in console is 'null' and calling methods on imageView I get null pointer exception

Upvotes: 0

Views: 402

Answers (1)

James_D
James_D

Reputation: 209330

You are setting the onKeyPressed handler for the Scene to invoke a method on an instance of Ball you created:

Ball ball = new Ball();
scene.setOnKeyPressed(e -> ball.moveBallOnKeyPress(e));

@FXML-annotated fields are, of course, only initialized in the controller. They will not somehow be initialized in other objects simply because they are instances of the same class. You need to set the event handler to refer to the actual controller:

@Override
public void start(Stage primaryStage) throws Exception{
    FXMLLoader loader = new FXMLLoader(getClass().getResource("sample.fxml"));
    Parent root = loader.load();
    primaryStage.setTitle("Hello World!");
    scene = new Scene(root, 600, 550);
    Ball ball = loader.getController();
    scene.setOnKeyPressed(e -> ball.moveBallOnKeyPress(e));
    // or scene.setOnKeyPressed(ball::moveBallOnKeyPress);
    primaryStage.setScene(scene);
    primaryStage.show();
}

Upvotes: 1

Related Questions