线程“main”中出现异常 java.lang.ExceptionInInitializerError,由 NullPointerException 引起?

问题描述 投票:0回答:1

这是我第一次尝试使用 JavaFX 的项目,我遇到了一些我不太理解的异常问题。我收到此错误消息:

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)

当我尝试运行此代码时:

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);
        }
    }
}

如果我删除开头的静态初始化,则不会出现错误消息。这里有人知道该怎么做吗?

此外,英语不是我的母语,如果我犯了任何语法错误,很抱歉。

java javafx nullpointerexception scene
1个回答
0
投票

您没有正确使用 JavaFX。您的代码至少存在两个问题:

  1. 您正在 JavaFX 平台启动之前创建 UI 对象(我相信,这是本例中

    NullPointerException
    的原因)。

  2. 您正在除

    JavaFX应用程序线程
    之外的线程上构造和修改Stage,这是不允许的。
    Scene
    也只能附加到 FX 线程上的
    Stage
    (尽管它可以在任何线程上创建和修改,直到并且除非它附加到正在显示的舞台)。

我建议在尝试使用 JavaFX 编写应用程序之前先研究更多有关 JavaFX 的信息。例如,您可以阅读“JavaFX 入门”指南,了解如何设置基本的 JavaFX 应用程序(使用任何主要的 Java IDE 和/或构建工具)。 javafx.application.Application

的Javadoc将解释JavaFX的生命周期。互联网上还有很多教程和书籍,您可以购买来了解有关 JavaFX 的更多信息。
请注意,典型的 JavaFX 应用程序将扩展其主类

Application

。所以,你的类应该看起来更像这样:

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);
        }
    }
}

虽然我不能保证解决你所有的问题,因为我不知道你的 
InventoryManagerGFX

Domain
类是如何实现的。另请注意,在这种情况下,
main
方法实际上并不是必需的(如果您将
DisplayTest
作为主类并且 JavaFX 位于模块路径上)。
顺便说一句,您可能需要重新考虑有关您的申请的一些事情:

    过度使用静态是糟糕设计的标志。您应该考虑使用正确的应用程序架构,例如
  1. Model-View-Controller

    (MVC)、Model-View-Presenter (MVP)、Model-View-ViewModel (MVVM) 等;使用依赖注入(这只是通过构造函数和/或方法传递对象的一种奇特方式);遵循坚实的原则;等等。

  2. 在 GUI(图形用户界面)应用程序中使用
  3. System.in

    可能很奇怪。它用于 CLI(命令行界面)应用程序。创建

    GUI 应用程序或CLI 应用程序,而不是两者的混合。请注意,GUI 应用程序本质上是
    事件驱动

© www.soinside.com 2019 - 2024. All rights reserved.