Странное исключение JavaFx !! Исключение в методе запуска приложения - PullRequest
0 голосов
/ 18 апреля 2020

Надеюсь, у вас все хорошо в этот трудный период,

Я разрабатываю клиент JavaFx для моих остальных веб-сервисов, и во время работы моего приложения есть странное исключение, которое указывает на мой класс LoginPresenter. hv проверил весь исходный путь, но ничего не сигнализировал, поэтому я пришел сюда, чтобы попросить о помощи, вот ошибка:

    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 Ответ

2 голосов
/ 18 апреля 2020

Ваш класс LoginPresenter находится (в соответствии с трассировкой стека) в пакете fr.orleans.univ.projet.view.

Использование LoginPresenter.class.getResourceAsStream("login.fxml") будет искать ресурс login.fxml в том же пакете, что и LoginPresenter находится в. Согласно вашему комментарию, вы поместили login.fxml в исходную папку src/main/java/resources (я предполагаю, что "ресурсы" - опечатка), которая (со стандартной конфигурацией в большинстве сред IDE или инструментов сборки) поместит ее в пакет по умолчанию в сборке.

Это можно исправить либо

  1. , указав абсолютный путь к файлу F XML. Так как у вас это есть в пакете по умолчанию, это означает использование

    LoginPresenter.class.getResourceAsStream("/login.fxml")
    

    (обратите внимание на ведущий /)

  2. или размещение login.fxml в том же пакете, который вы бы сделали, поместив его в исходную папку src/main/java/resources/fr/orleans/univ/projet/view.

В общем, я думаю, что последнее решение лучше.

Также необходимо убедиться, что файл F XML развернут во время сборки; если вы используете инструмент сборки, такой как Maven или Gradle, это должно происходить по умолчанию; если вы используете ванильную сборку из вашей IDE, вам может потребоваться настроить ее, чтобы это произошло.

Если вам требуется дальнейшее устранение неполадок, проверьте макет папки buid ( не исходная папка). В зависимости от вашего инструмента сборки или IDE, это может быть build, bin, target, target/classes, et c. Загляните в папку сборки и проверьте соотношение между LoginPresenter.class и login.fxml.

Одна немного не в топе c точка; Я настоятельно рекомендую использовать ресурсный URL для загрузки F XML, а не потока; т.е. использовать

LoginPresenter.class.getResource(...)

вместо

LoginPresenter.class.getResourceAsStream(...)

Причина в том, что потоковая версия метода загрузки не может установить свойство FXMLLoader 'location (потому что нет место указано); следовательно, например, разрешение местоположения не будет работать в файле F XML.

...