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

时间:2018-11-05 18:49:24

标签: java javafx scenebuilder

我想说的是,我在SO中看了很多东西,但没有帖子对我有帮助,所以我再次询问...

我正在尝试创建登录屏幕,但仍然出现相同的异常。我的目录结构如下: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$launchApplication$154(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$launchApplication1$161(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$174(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$172(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$173(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$48(GtkApplication.java:139)
    ... 1 more

到目前为止,我所读的所有内容都说:“这就是为什么FXML找不到控制器的原因!”,所以我检查了一下,这真的没问题。这是控制者声明:

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

我认为可以要求提供此信息:

2 个答案:

答案 0 :(得分:0)

有两种方法可以做到这一点。我喜欢方法1,因为它对我来说似乎更简单。

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

例如,如果我有一个java/hypnic/jerk/controllers/的层次结构,其中有一个MainController.java文件,并且我想加载一个将使用此java文件作为其控制器的FXML文件,则将其放入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"));

../表示向上一个目录/文件夹。因此,请根据您可能对项目进行遮光的方式,记住每个.都是该名称下的一个新文件夹,您需要添加一个../直到返回java文件夹。 / p>

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

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

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

现在请记住,这只是一个解释,您将不得不自行调整它。

希望这会有所帮助。

答案 1 :(得分:0)

实际上,您正在获得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();
}