I've been experimenting with a program in JavaFX that displays three images side-by-side along with three buttons below them. When you click a button, the card the button is below should be swapped for another image. I am attempting to use a single event handler for this and as such need to declare my imageView objects and buttons outside of the start() method. However, I am getting a NullPointerException on a line of code that does not even exist within the program.
Here is my code. All of this code is within the same Main class.
package application;
import javafx.application.*;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.image.*;
import javafx.geometry.*;
import java.io.*;
public class Main extends Application {
//IMAGES
//img 1 setup
final String img1Path = "src/application/c1.gif";
ImageView img1;
boolean img1Flip = false;
//img 2 setup
final String img2Path = "src/application/c2.gif";
ImageView img2;
boolean img2Flip = false;
//img 3 setup
final String img3Path = "src/application/c3.gif";
ImageView img3;
boolean img3Flip = false;
//img 4 setup
final String img4Path = "src/application/b1fv.gif";
//BUTTONS
//button 1 setup
Button button1;
//button 2 setup
Button button2;
//button 3 setup
Button button3;
@Override
public void start(Stage stage1) throws FileNotFoundException {
System.out.println("Compiled."); //debug
//image view setup
img1 = new ImageView(new Image(new FileInputStream(img1Path))); //creates an image view
img2 = new ImageView(new Image(new FileInputStream(img2Path))); //creates an image view
img3 = new ImageView(new Image(new FileInputStream(img3Path))); //creates an image view
//button setup
button1 = new Button("Flip");
button1.setOnAction((EventHandler<ActionEvent>) new ButtonHandler());
//button1.setId("button1");
button2 = new Button("Flip");
button2.setOnAction((EventHandler<ActionEvent>) new ButtonHandler());
//button2.setId("button2");
button3 = new Button("Flip");
button3.setOnAction((EventHandler<ActionEvent>) new ButtonHandler());
//button3.setId("button3");
//scene setup
final int sceneW = 400;
final int sceneH = 200;
//stage setup
final String stageTitle = "FlipImages";
System.out.println("Initialized."); //debug
try {
//STAGE SETUP
System.out.println("Setting Up"); //debug
stage1.setTitle(stageTitle);
FlowPane pane = new FlowPane(Orientation.VERTICAL);
Scene scene1 = new Scene(pane, sceneW, sceneH);
pane.setAlignment(Pos.CENTER);
//ADDING TO SCENE
System.out.println("Formatting."); //debug
HBox imagePanel = new HBox(img1, img2, img3);
HBox buttonPanel = new HBox();
imagePanel.setSpacing((double) 5);
buttonPanel.setSpacing((double) 10);
pane.getChildren().addAll(imagePanel, buttonPanel);
//FINAL STEPS
System.out.println("Generating."); //debug
stage1.setScene(scene1);
stage1.setResizable(false);
stage1.show();
}
catch(Exception e) {
System.out.println("Exception Caught."); //debug
e.printStackTrace();
}
}
class ButtonHandler implements EventHandler<ActionEvent> {
public void handle(ActionEvent a) {
try {
System.out.println("handle Image Creation"); //debug
//regular image setup
Image img1unflip = new Image(new FileInputStream(img1Path)); //creates an image
Image img2unflip = new Image(new FileInputStream(img2Path)); //creates an image
Image img3unflip = new Image(new FileInputStream(img3Path)); //creates an image
//flipped image setup
Image imgFlipped = new Image(new FileInputStream(img4Path)); //creates an image
System.out.println("Obtaining Source"); //debug
//String callId = ((Node) a.getSource()).getId(); //doesn't work well
Object source = a.getSource();
System.out.println("Flipping"); //debug
if (source == button1) {
if (img1Flip == false) {
img1 = new ImageView(imgFlipped);
}
else {
img1 = new ImageView(img1unflip);
}
}
else if (source == button2) {
if (img2Flip == false) {
img2 = new ImageView(imgFlipped);
}
else {
img2 = new ImageView(img2unflip);
}
}
else if (source == button3) {
if (img3Flip == false) {
img3 = new ImageView(imgFlipped);
}
else {
img3 = new ImageView(img3unflip);
}
}
}
catch (Exception e) {
System.out.println("Exception Caught: handle"); //debug
e.printStackTrace();
}
}
}
public void main(String[] args) {
launch(args);
}
}
Here is the console output. Notice that none of my debug statements are printed.
Exception in thread "main" java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:64)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1071)
Caused by: java.lang.NullPointerException: Cannot invoke "Object.getClass()" because "obj" is null
at java.base/java.lang.reflect.Method.invoke(Method.java:557)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
... 5 more
I would like to know why this error is taking place and how to fix it.