【问题标题】:JavaFX Project breaks when exported to runnable .jar? FXMLLoader related?JavaFX 项目在导出到可运行的 .jar 时中断? FXMLLoader 相关?
【发布时间】:2016-09-19 16:52:03
【问题描述】:

我一直在尝试将 JavaFX 项目导出为 .jar,但每当我运行它时,都会收到 NullPointerException;据说,它找不到 FXML。我不确定如何处理这个问题,我的项目结构有问题吗?我看了看:FXML layout not loaded when run jar outside Eclipse,但该解决方案似乎对我不起作用,并且有一个不同的问题。

项目托管在:https://github.com/Sunquyman/GameOfLife/tree/master/src

我在尝试运行时收到的堆栈跟踪:

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 main.Main.start(Main.java:21)
    at com.sun.javafx.application.LauncherImpl.lambda$launchApplication1$162(LauncherImpl.java:863)
    at com.sun.javafx.application.PlatformImpl.lambda$runAndWait$175(PlatformImpl.java:326)
    at com.sun.javafx.application.PlatformImpl.lambda$null$173(PlatformImpl.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.application.PlatformImpl.lambda$runLater$174(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$49(GtkApplication.java:139)
    at java.lang.Thread.run(Thread.java:745)

真的很困惑为什么会这样;如果它在 Eclipse 中运行良好,为什么它会作为导出中断?

提前致谢!

【问题讨论】:

  • 当您将其导出为 .jar 时,您是否也包含了那些 .fxml 文件?
  • 是的,.jar 包含 FXML。
  • 可以肯定的一点是他在抱怨这一行 Parent root = FXMLLoader.load(getClass().getResource("../view/GUI.fxml"));
  • 你确定这条线的结构很好吗?
  • 我下载了你的代码,它与 (../) 有关。如果你将 .fxml 和 .css 放在文件夹 main 中它可以工作,但我想知道为什么 (../)导致这个问题...

标签: java eclipse javafx jar


【解决方案1】:

首先,您必须像这样创建一个 resources 文件夹:

为此,请右键单击项目->新建->资源文件夹->根据需要命名,但一个不错的选项是 资源

然后我在这里修改了您的代码:

主类:

public class Main extends Application {
@Override
public void start(Stage primaryStage) {
    try {

        //You have to Load the font before using it into css!!
        Font.loadFont(getClass().getResourceAsStream("/resources/fonts/8bit.ttf"), 14);
        Scene scene = new Scene(new GUIController());
        scene.getStylesheets().add(getClass().getResource("/view/application.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.setTitle("Game of Life Settings");
        primaryStage.show();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

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

GUIController: 请记住,在 .fxml 文件中我使用了 root 和 !default Controller,所以它现在看起来像这样(使用 SceneBuilder)。基本上这样做你可以使用 GUIController 类一次。

public class GUIController extends AnchorPane implements Initializable {

..........

private final String lotOn = "/music/soundfx/lensoftruth_on.mp3";
private final String lotOff = "/music/soundfx/lensoftruth_off.mp3";

 .......

//Constructor
public GUIController(){
    FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/GUI.fxml"));
    loader.setRoot(this);
    loader.setController(this);

    try {
        loader.load();
    } catch (IOException e) {
        e.printStackTrace();
    }
  }


.......

 }

关于 CSS: 最后我修改了 in css 文件,因为 css 字体在添加 css(check this here) 之前被加载到代码中:

@font-face {

-fx-font-family: "8bit";

}

最后关于/:

如果你为一个类调用 getResource() 并且没有在前面加上 /,则路径被认为是相对于该类的包的。Check this here

你快乐吗? :)

【讨论】:

  • 好的,谢谢!但是,我认为在代码中包含资源和加载 css 的部分是不必要的......我尝试了 CSS font-face 行:url('file:fonts/8bit.ttf');,它最终完美地工作!所以重申一下,我认为快速的解决方案是简单地使用以“/”开头的相对文件路径进行 FXML 和 CSS 加载,并附加“file:”以进行相对 @font-face 加载。无论如何,非常感谢您提供这些资源,帮助您更好地理解这一点。尤其是提供关于“/”的关键信息,这非常重要!
【解决方案2】:

你的代码:

  Parent root = FXMLLoader.load(getClass().getResource("../view/GUI.fxml"));

尝试将 GUI.fxml 放入 resources 文件夹并将代码更改为:

  Parent root = FXMLLoader.load(getClass().getResource("GUI.fxml"));

【讨论】:

  • 我没有资源文件夹...?等等,我应该做一个吗?
  • 你的项目没有? Eclipse 让它自动
  • 不,它没有...当我新建一个 JavaFX 项目时,Eclipse 自动创建了一些文件,但我找不到资源文件夹
  • 所以右键项目并新建一个名为resources的源文件夹
  • 好的,所以我创建了一个名为“resources”的文件夹,插入了 FXML 文件,并将代码更改为 .getResource("GUI.fxml"),但它甚至无法在 Eclipse 中运行。还有什么我应该做的吗?
猜你喜欢
  • 2021-10-17
  • 2016-01-13
  • 2021-08-05
  • 2021-10-22
  • 2020-10-29
  • 2020-09-08
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
相关资源
最近更新 更多