JavaFx怪异异常!应用程序启动方法异常

时间:2020-04-18 14:39:17

标签: javafx webservice-client openjfx

我希望您在这个困难时期过得很好,

我正在为其余的Web服务开发JavaFx客户端,并且在运行我的应用程序时,出现了一个怪异的异常,该异常指向我的LoginPresenter类,我检查了所有源路径,但没有任何信号,因此我来这里询问对于某些帮助,错误如下:

    Exception in Application start method
java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplicationWithArgs(LauncherImpl.java:464)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication(LauncherImpl.java:363)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:567)
    at java.base/sun.launcher.LauncherHelper$FXHelper.main(LauncherHelper.java:1051)
Caused by: java.lang.RuntimeException: Exception in Application start method
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.launchApplication1(LauncherImpl.java:900)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication$2(LauncherImpl.java:195)
    at java.base/java.lang.Thread.run(Thread.java:830)
Caused by: java.lang.NullPointerException: inputStream is null.
    at javafx.fxml/javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2480)
    at javafx.fxml/javafx.fxml.FXMLLoader.load(FXMLLoader.java:2450)
    at fr.orleans.univ.projet/fr.orleans.univ.projet.view.LoginPresenter.getInstance(LoginPresenter.java:39)
    at fr.orleans.univ.projet/fr.orleans.univ.projet.PrimaryController.showLogin(PrimaryController.java:22)
    at fr.orleans.univ.projet/fr.orleans.univ.projet.App.start(App.java:30)
    at javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
    at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication._runLoop(Native Method)
    at javafx.graphics/com.sun.glass.ui.gtk.GtkApplication.lambda$runLoop$11(GtkApplication.java:277)
    ... 1 more
Exception running application fr.orleans.univ.projet.App

这是我的代码:

控制器PrimaryController.class

public class PrimaryController {

    private Stage stage;
    private Service service;

    public PrimaryController(Stage stage, Service service) {
        this.stage = stage;
        this.service = service;
    }

    public void showLogin(){
        LoginPresenter login = LoginPresenter.getInstance(this);
        Scene scene = new Scene(login.getRoot());
        stage.setScene(scene);
        stage.show();
    }

    public void tenteLogin(String username, String password) {
        service.login(username,password);
        if(service.isAuthenticated()){
            System.out.println("Connecté!");
        }
    }
}

这是我的LoginPresenter.class

public class LoginPresenter {

    private PrimaryController primaryController;

    public void setPrimaryController(PrimaryController primaryController){
        this.primaryController=primaryController;
    }

    @FXML
    private TextField username;
    @FXML
    private PasswordField password;
    @FXML
    private Parent root;

    public Parent getRoot(){
        return root;
    }

    public void login(ActionEvent actionEvent)  {
        primaryController.tenteLogin(username.getText(),password.getText());
    }

    public  static LoginPresenter getInstance(PrimaryController primaryController){
        FXMLLoader loader = new FXMLLoader();
        try {
            Parent root = loader.load(LoginPresenter.class.getResourceAsStream("login.fxml"));
        } catch (IOException e){
            e.printStackTrace();
        }
        LoginPresenter instance = loader.getController();
        instance.setPrimaryController(primaryController);

        return instance;
    }
}

这是我的App.class

public class App extends Application {

   // private static Scene scene;


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


    @Override
    public void start(Stage stage) {
        Service service = new ServiceProxy();
        PrimaryController primaryController = new PrimaryController(stage,service);
        primaryController.showLogin();
    }
}

最后是我的login.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>

<BorderPane fx:id="root" prefHeight="200.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/10.0.2-internal" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fr.orleans.univ.projet.view.LoginPresenter">
   <top>
      <Label text="Login" BorderPane.alignment="CENTER">
         <font>
            <Font size="24.0" />
         </font>
      </Label>
   </top>
   <center>
      <GridPane BorderPane.alignment="CENTER">
         <columnConstraints>
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="94.0" minWidth="10.0" prefWidth="72.0" />
            <ColumnConstraints hgrow="SOMETIMES" maxWidth="158.0" minWidth="10.0" prefWidth="128.0" />
         </columnConstraints>
         <rowConstraints>
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
            <RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
         </rowConstraints>
         <children>
            <Label focusTraversable="false" text="Username" />
            <Label focusTraversable="false" text="Password" GridPane.rowIndex="1" />
            <TextField fx:id="username" GridPane.columnIndex="1" />
            <PasswordField fx:id="password" GridPane.columnIndex="1" GridPane.rowIndex="1" />
         </children>
      </GridPane>
   </center>
   <bottom>
      <Button defaultButton="true" mnemonicParsing="false" onAction="#login" text="Login" BorderPane.alignment="CENTER">
         <opaqueInsets>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
         </opaqueInsets></Button>
   </bottom>
</BorderPane>

1 个答案:

答案 0 :(得分:2)

您的LoginPresenter类在栈fr.orleans.univ.projet.view中(根据堆栈跟踪)。

使用LoginPresenter.class.getResourceAsStream("login.fxml")将在login.fxml所在的同一包中查找资源LoginPresenter。根据您的评论,您将login.fxml放在了源文件夹{ {1}}(我认为“资源”是拼写错误),它将(在大多数IDE或构建工具中具有标准配置)将其放置在构建的默认包中。

您可以解决此问题

  1. 通过提供FXML文件的绝对路径。由于您在默认软件包中有此文件,因此这意味着使用

    src/main/java/resources

    (请注意开头的LoginPresenter.class.getResourceAsStream("/login.fxml")

  2. 或将/放在同一包中,您可以将其放在源文件夹login.fxml中。

通常,我认为后一种解决方案更好。

您还需要确保在构建过程中部署了FXML文件。如果您使用的是Maven或Gradle等构建工具,则默认情况下会发生这种情况;如果您在IDE中使用的是原始版本,则可能需要对其进行配置以确保这种情况发生。

如果需要进一步的疑难解答,则应检查 buid 文件夹(而不是源文件夹)的布局。根据您的构建工具或IDE,它可以是src/main/java/resources/fr/orleans/univ/projet/viewbuildbintarget等之一。在构建文件夹中查看并检查{ {1}}和target/classes

一个稍微偏离主题的观点;我强烈建议使用资源URL而非流来加载FXML。即使用

LoginPresenter.class

代替

login.fxml

原因是load方法的流版本无法设置LoginPresenter.class.getResource(...) 的{​​{1}}属性(因为未指定位置);因此,例如,location resolution在FXML文件中不起作用。