0

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

fmatt
  • 464
  • 1
  • 5
  • 15
  • @James_D I made it non-static and the problem yet exists . I really dont know what's wrong and I'm confused to death :( – fmatt May 26 '20 at 18:53
  • Where are you calling that method from? There are no elements in your FXML file with event handlers set as `moveBallOnKeyPress`. – James_D May 26 '20 at 18:54
  • I setOnKeyPressed for my scene and call this method for the event handler – fmatt May 26 '20 at 18:55
  • Post the code. How are you actually invoking that on the controller instance? – James_D May 26 '20 at 18:55
  • You're not calling `moveBallOnKeyPress` on the controller. You're calling it on an object you created. The image view won't be magically initialized in the object - it's only initialized in the controller. – James_D May 26 '20 at 18:58

1 Answers1

1

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();
}
James_D
  • 201,275
  • 16
  • 291
  • 322