我希望您在这个困难时期过得很好,
我正在为其余的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>
答案 0 :(得分:2)
您的LoginPresenter
类在栈fr.orleans.univ.projet.view
中(根据堆栈跟踪)。
使用LoginPresenter.class.getResourceAsStream("login.fxml")
将在login.fxml
所在的同一包中查找资源LoginPresenter
。根据您的评论,您将login.fxml
放在了源文件夹{ {1}}(我认为“资源”是拼写错误),它将(在大多数IDE或构建工具中具有标准配置)将其放置在构建的默认包中。
您可以解决此问题
通过提供FXML文件的绝对路径。由于您在默认软件包中有此文件,因此这意味着使用
src/main/java/resources
(请注意开头的LoginPresenter.class.getResourceAsStream("/login.fxml")
)
/
放在同一包中,您可以将其放在源文件夹login.fxml
中。 通常,我认为后一种解决方案更好。
您还需要确保在构建过程中部署了FXML文件。如果您使用的是Maven或Gradle等构建工具,则默认情况下会发生这种情况;如果您在IDE中使用的是原始版本,则可能需要对其进行配置以确保这种情况发生。
如果需要进一步的疑难解答,则应检查 buid 文件夹(而不是源文件夹)的布局。根据您的构建工具或IDE,它可以是src/main/java/resources/fr/orleans/univ/projet/view
,build
,bin
,target
等之一。在构建文件夹中查看并检查{ {1}}和target/classes
。
一个稍微偏离主题的观点;我强烈建议使用资源URL而非流来加载FXML。即使用
LoginPresenter.class
代替
login.fxml
原因是load方法的流版本无法设置LoginPresenter.class.getResource(...)
的{{1}}属性(因为未指定位置);因此,例如,location resolution在FXML文件中不起作用。