Exception in thread "main" java.lang.ExceptionInInitializerError, caused by NullPointerException?

322 views Asked by At

This is my first time attempting a project using JavaFX and i'm having some trouble with an exception that i don't quite understand. I'm getting this error message:

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.NullPointerException: Cannot invoke "com.sun.glass.ui.Timer.resume()" because "this.pulseTimer" is null
    at com.sun.javafx.tk.quantum.QuantumToolkit.resumeTimer(QuantumToolkit.java:542)
    at com.sun.javafx.tk.quantum.QuantumToolkit$PulseTask.set(QuantumToolkit.java:213)
    at com.sun.javafx.tk.quantum.QuantumToolkit.requestNextPulse(QuantumToolkit.java:906)
    at javafx.scene.Parent.markDirtyLayout(Parent.java:940)
    at javafx.scene.Parent.requestLayout(Parent.java:964)
    at javafx.scene.layout.StackPane.requestLayout(StackPane.java:322)
    at javafx.scene.Scene$8.invalidated(Scene.java:1247)
    at javafx.beans.property.ObjectPropertyBase.markInvalid(ObjectPropertyBase.java:112)
    at javafx.beans.property.ObjectPropertyBase.set(ObjectPropertyBase.java:147)
    at javafx.scene.Scene.setRoot(Scene.java:1196)
    at javafx.scene.Scene.<init>(Scene.java:360)
    at javafx.scene.Scene.<init>(Scene.java:211)
    at Presentation.DisplayTest.<clinit>(DisplayTest.java:11)

When i attempt to run this code:

package Presentation;

import Domain.Domain;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class DisplayTest {
    static StackPane root = new StackPane();
    static Scene scene = new Scene(root);
    static Stage primaryStage = new Stage();

    public static void main(String[] args) {
        System.out.println("Velkommen til (Spil navn)!");
        Domain.initEverything();
        primaryStage.setTitle("Klima Kurv");
        primaryStage.setScene(scene);
        InventoryManagerGFX.initInventoryManagerGFX(primaryStage);
        primaryStage.show();
        System.out.println("Spillet er færdigt!");
    }

    public static void gameOnGoing() {
        while (!Domain.GetIsDone()) {
            System.out.print("> ");
            String line = Domain.GetNextLine();
            Domain.dispatch(line);
        }
    }
}

The error message does not appear if i delete the static initialisations at the beginning. Does anyone here know what to do?

Also, english is not my first language so sorry if i have made any grammatical errors.

1

There are 1 answers

0
Slaw On

You are not using JavaFX correctly. There are at least two problems with your code:

  1. You are creating UI (user interface) objects before the JavaFX platform has been started (the cause, I believe, of the NullPointerException in this case).

  2. You are constructing and modifying a Stage on a thread other than the JavaFX Application Thread, which is not allowed.

I recommend researching more about JavaFX before trying to write an application with it. For example, you can read the Getting Started with JavaFX guide to see how to set up a basic JavaFX application (with any of the major Java IDEs and/or build tools, whether your own code is modular or not). And the Javadoc of javafx.application.Application will explain the lifecycle of JavaFX. There are also quite a few tutorials out there on the internet, books you can buy, and other Stack Overflow Q&As regarding JavaFX which will help you learn more about JavaFX.

There are a few ways to start the JavaFX platform. However, a typical JavaFX application will do it by having its main class extend Application. So, your class should potentially look more like this:

package Presentation;

import Domain.Domain;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class DisplayTest extends Application {

    public static void main(String[] args) {
        Application.launch(DisplayTest.class, args);
    }

    @Override
    public void start(Stage primaryStage) {
        StackPane root = new StackPane();
        Scene scene = new Scene(root);

        System.out.println("Velkommen til (Spil navn)!");
        Domain.initEverything();
        primaryStage.setTitle("Klima Kurv");
        primaryStage.setScene(scene);
        InventoryManagerGFX.initInventoryManagerGFX(primaryStage);
        primaryStage.show();
        System.out.println("Spillet er færdigt!");
    }

    public static void gameOnGoing() {
        while (!Domain.GetIsDone()) {
            System.out.print("> ");
            String line = Domain.GetNextLine();
            Domain.dispatch(line);
        }
    }
}

Though I cannot promise that fixes all your problems, as I have no idea how your Domain and InventoryMangagerGFX classes are implemented. Also, note that in this case, the main method is not actually necessary (if you have DisplayTest as the main class and JavaFX is on the module-path).

On a related note, you might want to reconsider a few things about your application:

  1. Overuse of static state is a sign of bad design. Java is object-oriented, so you should make use of objects; follow SOLID principles; use dependency injection (which is just a fancy way of saying pass objects via constructors and/or methods); and so on. Additionally, consider using a proper application architecture like Model-View-Controller (MVC), Model-View-Presenter (MVP), Model-View-ViewModel (MVVM), or another.

  2. It is strange to use System.in, presumably as part of the GetNextLine() implementation, in a GUI (Graphical User Interface) application. Reading from the standard input stream is something done in CLI (Command Line Interface) applications. Create either a GUI application or a CLI application, not a mix of both. Note that GUI applications are inherently event-driven, so having that while (!Domain.GetIsDone()) loop does not make much sense.

  3. Follow standard Java naming conventions. Or, at the very least, you should be consistent.