问题描述
我在使用 jpackage 打包程序时遇到的问题需要帮助。该程序是在 Eclipse 中创建的非模块化 JavaFX 应用程序。在 Eclipse 中,应用程序可以准确地编译和运行。但是当我使用命令提示符进行编译和运行时,编译工作但应用程序不再运行。我收到以下错误消息:
java.lang.NullPointerException:无法调用 “java.net.URL.toExternalForm()”因为返回值 “java.lang.class.getResource(String)”为空 在 application.Main.start(Main.java:158) 在 javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) 在 javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) 在 javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) 在 java.base/java.security.AccessController.doPrivileged(AccessController.java:391) 在 javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) 在 javafx.graphics/com.sun.glass.ui.invokelaterdispatcher$Future.run(invokelaterdispatcher.java:96) 在 javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native 方法) 在 javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174) 在 java.base/java.lang.Thread.run(Thread.java:832)
尽管如此,jpackage 会创建一个没有任何错误或警告消息的安装程序。使用创建的安装程序进行安装也可以正常工作。但是当我启动我的应用程序时,我的 GUI 不会显示。更准确地说:GUI 的第一部分是一些使用标准布局的设置窗口。显示设置窗口,但不显示“主”GUI。因此,我认为问题的根源在于缺少 css 文件。 我的假设是否正确,如果是:我该如何解决?
提前致谢!
附录:这是我的命令提示符输入:
-
dir /s /b *.java > 源文件.txt
-
javac --module-path %PATH_TO_FX% --add-modules javafx.controls,javafx.fxml –d out @sources.txt
-
java --module-path %PATH_TO_FX% --add-modules javafx.controls,javafx.fxml –cp out application.Main(这里出现错误)
-
jar --create --file=libs/sample1.jar --main-class=application.Main –C out .
-
%JAVA_HOME%\bin\jpackage --type exe –i libs --main-jar sample1.jar –n Sample1 --module-path %PATH_TO_FX_MODS% --add-modules javafx.controls,javafx. fxml --main-class application.Main --win-shortcut --win-menu --win-dir-chooser
css-file 与 main-class 位于同一目录中。
解决方法
谢谢你的提示。我仔细阅读了带有链接的手册。现在我明白我的代码可能有问题。之前我认为 jpackage 和我在命令提示符中的命令有问题。与此同时,我重新编写了代码并用 URL-classes 替换了 File-classes。但我仍然遇到类似的错误。因此我写了一个新的(简单的)代码来重现错误。
package application;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.*;
public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
BorderPane root = new BorderPane();
Scene scene = new Scene(root,600,500);
URL urlImage = getClass().getResource("image.jpg");
Image image = new Image(urlImage.toExternalForm(),400,true,true);
ImageView imageView = new ImageView(image);
root.setCenter(imageView);
Label headline = new Label("Example Image");
URL urlStyles = getClass().getResource("styles.css");
headline.getStylesheets().add(urlStyles.toExternalForm());
root.setTop(headline);
Button button = new Button();
URL urlFile = getClass().getResource("text.txt");
String temp = urlFile.toString().replaceFirst("file:/","");
button.setText(read(temp));
root.setBottom(button);
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
public String read (String file) throws IOException {
FileReader fileReader = new FileReader(file);
BufferedReader in = new BufferedReader(fileReader);
try {
String str = in.readLine();
in.close();
return str;
} catch(IOException e) {
e.printStackTrace();
return "Error";
}
}
}
在使用命令提示符进行编译时,我仍然收到一个错误:
java.lang.NullPointerException:无法调用 "java.net.URL.toExternalForm()" 因为 "" 为空 在 application.Main.start(Main.java:25) 在 javafx.graphics/com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$9(LauncherImpl.java:846) 在 javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runAndWait$12(PlatformImpl.java:455) 在 javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428) 在 java.base/java.security.AccessController.doPrivileged(AccessController.java:391) 在 javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427) 在 javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96) 在 javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native 方法) 在 javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174) 在 java.base/java.lang.Thread.run(Thread.java:832)
我是否尝试加载图像(代码中的第一段)、css(第二段)或 txt 文件(最后一段)都没有关系。所有这些文件(图片、css、txt)都和主类在同一个目录下。
也许我错过了树林里的森林,但我认为我使用了 URL 类,就像指南解释的那样。我在下面有任何进一步的建议。谢谢!