这是我第一次尝试使用 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);
}
}
}
如果我删除开头的静态初始化,则不会出现错误消息。这里有人知道该怎么做吗?
此外,英语不是我的母语,如果我犯了任何语法错误,很抱歉。
您没有正确使用 JavaFX。您的代码至少存在两个问题:
您正在 JavaFX 平台启动之前创建 UI 对象(我相信,这是本例中
NullPointerException
的原因)。
您正在除
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 位于模块路径上)。顺便说一句,您可能需要重新考虑有关您的申请的一些事情:
(MVC)、Model-View-Presenter (MVP)、Model-View-ViewModel (MVVM) 等;使用依赖注入(这只是通过构造函数和/或方法传递对象的一种奇特方式);遵循坚实的原则;等等。
System.in
可能很奇怪。它用于 CLI(命令行界面)应用程序。创建
GUI 应用程序或CLI 应用程序,而不是两者的混合。请注意,GUI 应用程序本质上是事件驱动。