应用程序启动方法异常 - JavaFX

Application Start Method exception - JavaFX

我想说我在 SO 中看了很多并且 none 的帖子对我有帮助,所以我再次问...

我正在尝试创建一个登录屏幕,但我仍然遇到同样的异常。我的目录结构如下所示:check here

我的代码如下所示:

    public class main extends Application {

        @Override
        public void start(Stage stage) throws Exception {
            Parent root = FXMLLoader.load(getClass().getResource("fxml/loginScene.fxml"));
          //Parent root = FXMLLoader.load(getClass().getResource("../login/login.fxml"));
          //Parent root = FXMLLoader.load(getClass().getResource("login.fxml"));
          //Parent root = FXMLLoader.load(getClass().getResource("src/relativepath//login/login.fxml"));
          //Parent root = FXMLLoader.load(getClass().getResource("/home/somepath/src/relativepath/login/login.fxml"));
          //Parent root = FXMLLoader.load(getClass().getResource("fxml/loginScene.fxml"));

            stage.setScene(new Scene(root));
            stage.show();
        }

        public static void main(String[] args) {
            launch(args);
        }
    }

这是我得到的异常:

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: Location is required.
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3207)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124)
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104)
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097)
    at br.com.fulltime.fullcam.mosaicoDesktop.main.Main.start(Main.java:12)
    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.gtk.GtkApplication._runLoop(Native Method)
    at com.sun.glass.ui.gtk.GtkApplication.lambda$null(GtkApplication.java:139)
    ... 1 more

到目前为止我读到的所有内容都说"That's why FXML can not find the controller!",所以我检查了一下,确实没问题。这是控制器语句:

fx:controller="br.com.mycompany.myproduct.module.login.controllerLogin">

我认为可以请求此信息:

有几种方法可以做到这一点。我更喜欢方法一,因为它对我来说更直接。

要加载资源,您需要知道路径。控制器知道它们自己的路径,所以我使用它们。

例如,如果我有一个 java/hypnic/jerk/controllers/ 的层次结构,其中有一个 MainController.java 文件,我想加载一个 FXML 文件,它将使用这个 java 文件作为它的控制器,我把它放在resources/hypnic/jerk/controllers/。然后,当我调用 FXMLLoader.load(); 时,我会这样做:

FXMLLoader.load(MainController.class.getResource("mainScreen.fxml"));

根据我的理解和看法,这告诉加载程序使用 MainController 规定的路径并从那里的路径获取 mainScreen.fxml 文件。

在我看来,这是最简单的方法,因为它迫使您保持命名约定,并且您知道每个 FXML 文件在哪里用于关联的控制器文件。

您也可以使用路径找到它,在您的情况下,您的 loginScene.fxmlfxml/ 文件夹中,所以从 Main 我会做

FXMLLoader.load(getClass().getResource("../../../../fxml/loginScene.fxml"));

../的意思是,上一directory/folder。因此,根据您涂黑的项目数量,请记住每个 . 都是该名称的新文件夹,您需要添加 ../ 直到返回 java 文件夹。

让我们使用路径为 java/br/com/one/two/three/main/ 的示例。由于您的代码显示 getClass().getResource("fxml/loginScene.fxml") 您正在 resources/br/com/one/two/three/fxml/ 文件夹中查找该文件。该路径基于调用 class Main.java,因此无法找到它,因为 resources 中的路径不存在。

因此您需要使用 ../ 退出这些目录,直到您到达它为止。每个 ../ 代表另一层。所以在这种情况下,如果我的计算正确,您将需要 5 ../ 才能找到 fxml/loginScene.fxml 文件。所以最终结果将是

FXMLLoader.load(getClass().getResource("../../../../../fxml/loginScene.fxml"));

请记住,这只是一个解释,您必须自行调整。

希望对您有所帮助。

事实上,您获得了 NPE。尝试调试,然后,你可以试试这个:

public void start(Stage stage) throws Exception {
    FXMLLoader loader = new FXMLLoader(this.getClass().getResource("/fxml/loginScene.fxml"));
    Parent root = loader.load();
    stage.setScene(new Scene(root));
    stage.show();
}