导出到runnable .jar时,JavaFX项目会中断吗? FXMLLoader相关?

时间:2016-05-22 22:26:09

标签: java eclipse javafx jar

我一直在尝试将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中运行良好,为什么它会作为导出中断?

提前致谢!

2 个答案:

答案 0 :(得分:1)

您的代码:

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

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

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

答案 1 :(得分:1)

首先,您必须创建一个资源文件夹,如下所示:

要执行此操作,请右键单击Project-> New->资源文件夹 - >根据需要为其命名,但一个不错的选项是资源

enter image description here

然后我修改了你的代码,如下所示:

主要类别:

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和!默认控制器,所以现在看起来像这样(使用SceneBuilder)。基本上这样你可以使用GUIController类不止一次。

enter image description here

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: 最后在我修改的css文件中导致css字体在加入css(check this here)之前加载到代码中:

@font-face {

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

}

最后关于/:

如果为类调用getResource()并且不预先添加/,则该路径被认为是相对于类的包。Check this here

  你快乐吗? :)