我在 JavaFX 应用程序中遇到 java.lang.reflect.InvocationTargetException 异常,我不知道如何修复它
I'm getting an java.lang.reflect.InvocationTargetException exception in JavaFX app and I have no idea how to fix it
我正在构建一个小型 D&D 副项目,但在浏览 JavaFX 时遇到问题。我试图在同一个舞台上移动通过几个场景。我正在使用 MVC 设计并在调用控制器时通过 primaryStage。但是,当我尝试从我的 UI class 调用并从我的控制器获取舞台时,它会抛出 InvocationTargetException。
主要Class:
package dnd;
import javafx.application.Application;
import javafx.stage.Stage;
public class DnD extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Dungeons and Dragons");
StartMenuCtrl startMenuCtrl = new StartMenuCtrl(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
开始菜单控制器Class:
package dnd;
import javafx.stage.Stage;
public class StartMenuCtrl {
private final StartMenuUI startMenuUI;
private final Stage primaryStage;
public StartMenuCtrl(Stage primaryStage) {
this.startMenuUI = new StartMenuUI(this);
this.primaryStage = new Stage();
}
public void newButtonIsPressed() {
System.out.println("New Button is pressed");
}
public void createButtonIsPressed() {
System.out.println("Create Button is pressed");
CreateCharCtrl createCharCtrl = new CreateCharCtrl(primaryStage);
}
public void loadButtonIsPressed() {
System.out.println("Load Button is pressed");
}
public void joinButtonIsPressed() {
System.out.println("Join Button is pressed");
}
public Stage getStage() {
return this.primaryStage;
}
}
开始菜单UIClass:
package dnd;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class StartMenuUI {
private final StartMenuCtrl startMenuCtrl;
private final Text title;
private final Button newBtn;
private final Button createBtn;
private final Button loadBtn;
private final Button joinBtn;
public StartMenuUI(StartMenuCtrl startMenuCtrl) {
this.startMenuCtrl = startMenuCtrl;
this.title = new Text();
this.newBtn = new Button("New Game");
this.createBtn = new Button("Create Character");
this.loadBtn = new Button("Load Saved Game");
this.joinBtn = new Button("Join Game");
initComponents();
}
private void initComponents() {
Group root = new Group(title, newBtn, createBtn, loadBtn, joinBtn);
Scene scene = new Scene(root, 1280, 720);
Stage stage = startMenuCtrl.getStage();
stage.setScene(scene);
}
}
错误:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at dnd.StartMenuUI.initComponents(StartMenuUI.java:70)
at dnd.StartMenuUI.<init>(StartMenuUI.java:25)
at dnd.StartMenuCtrl.<init>(StartMenuCtrl.java:10)
at dnd.DnD.start(DnD.java:11)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater3(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null7(WinApplication.java:177)
... 1 more
如有任何帮助,我们将不胜感激!我在这个项目中还很早,所以也将不胜感激 :)
您遇到了初始化顺序问题。在您的 StartMenuCtrl
构造函数中,您将对 this
的引用传递给 StartMenuUI
构造函数。 StartMenuUi
构造函数然后调用 initComponents
,它调用 startMenuCtrl.getStage()
... 但是那个方法 returns null
因为 StartMenuCtrl 构造函数还没有完成执行,并且还没有尚未初始化其 primaryStage
字段。
尝试重新排序 StartMenuCtrl 构造函数中的行,使它们按以下顺序排列:
this.primaryStage = new Stage(); // this needs to happen first!
this.startMenuUI = new StartMenuUI(this);
这个问题说明了为什么一般来说,it's best not to let the this
reference escape during object construction。
我正在构建一个小型 D&D 副项目,但在浏览 JavaFX 时遇到问题。我试图在同一个舞台上移动通过几个场景。我正在使用 MVC 设计并在调用控制器时通过 primaryStage。但是,当我尝试从我的 UI class 调用并从我的控制器获取舞台时,它会抛出 InvocationTargetException。
主要Class:
package dnd;
import javafx.application.Application;
import javafx.stage.Stage;
public class DnD extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Dungeons and Dragons");
StartMenuCtrl startMenuCtrl = new StartMenuCtrl(primaryStage);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
开始菜单控制器Class:
package dnd;
import javafx.stage.Stage;
public class StartMenuCtrl {
private final StartMenuUI startMenuUI;
private final Stage primaryStage;
public StartMenuCtrl(Stage primaryStage) {
this.startMenuUI = new StartMenuUI(this);
this.primaryStage = new Stage();
}
public void newButtonIsPressed() {
System.out.println("New Button is pressed");
}
public void createButtonIsPressed() {
System.out.println("Create Button is pressed");
CreateCharCtrl createCharCtrl = new CreateCharCtrl(primaryStage);
}
public void loadButtonIsPressed() {
System.out.println("Load Button is pressed");
}
public void joinButtonIsPressed() {
System.out.println("Join Button is pressed");
}
public Stage getStage() {
return this.primaryStage;
}
}
开始菜单UIClass:
package dnd;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class StartMenuUI {
private final StartMenuCtrl startMenuCtrl;
private final Text title;
private final Button newBtn;
private final Button createBtn;
private final Button loadBtn;
private final Button joinBtn;
public StartMenuUI(StartMenuCtrl startMenuCtrl) {
this.startMenuCtrl = startMenuCtrl;
this.title = new Text();
this.newBtn = new Button("New Game");
this.createBtn = new Button("Create Character");
this.loadBtn = new Button("Load Saved Game");
this.joinBtn = new Button("Join Game");
initComponents();
}
private void initComponents() {
Group root = new Group(title, newBtn, createBtn, loadBtn, joinBtn);
Scene scene = new Scene(root, 1280, 720);
Stage stage = startMenuCtrl.getStage();
stage.setScene(scene);
}
}
错误:
Exception in Application start method
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:389)
at com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:328)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:767)
Caused by: java.lang.RuntimeException: Exception in Application start method
at com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:917)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication4(LauncherImpl.java:182)
at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.NullPointerException
at dnd.StartMenuUI.initComponents(StartMenuUI.java:70)
at dnd.StartMenuUI.<init>(StartMenuUI.java:25)
at dnd.StartMenuCtrl.<init>(StartMenuCtrl.java:10)
at dnd.DnD.start(DnD.java:11)
at com.sun.javafx.application.LauncherImpl.lambda$launchApplication11(LauncherImpl.java:863)
at com.sun.javafx.application.PlatformImpl.lambda$runAndWait4(PlatformImpl.java:326)
at com.sun.javafx.application.PlatformImpl.lambda$null2(PlatformImpl.java:295)
at java.security.AccessController.doPrivileged(Native Method)
at com.sun.javafx.application.PlatformImpl.lambda$runLater3(PlatformImpl.java:294)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null7(WinApplication.java:177)
... 1 more
如有任何帮助,我们将不胜感激!我在这个项目中还很早,所以也将不胜感激 :)
您遇到了初始化顺序问题。在您的 StartMenuCtrl
构造函数中,您将对 this
的引用传递给 StartMenuUI
构造函数。 StartMenuUi
构造函数然后调用 initComponents
,它调用 startMenuCtrl.getStage()
... 但是那个方法 returns null
因为 StartMenuCtrl 构造函数还没有完成执行,并且还没有尚未初始化其 primaryStage
字段。
尝试重新排序 StartMenuCtrl 构造函数中的行,使它们按以下顺序排列:
this.primaryStage = new Stage(); // this needs to happen first!
this.startMenuUI = new StartMenuUI(this);
这个问题说明了为什么一般来说,it's best not to let the this
reference escape during object construction。