JavaFX和maven:NullPointerException:位置是必需的

我一直在尝试使用JavaFX设置Maven。 尽管我对Maven和JavaFX缺乏经验,但我并不认为这是一个很大的挑战。 我的Java知识非常可靠(包括Swing),并且没想到设置它会有这么大的困难。

我开始使用IntelliJ 13.0 Community Edition提供的JavaFX项目。 我的Main类中的代码相对较小:

package sample; import javafx.application.Application; import javafx.fxml.FXMLLoader; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.stage.Stage; public class Main extends Application { @Override public void start(Stage primaryStage) throws Exception { //getClass().getResource("../../resources/sample.fxml"); Parent root = FXMLLoader.load(getClass().getResource("../sample.fxml")); primaryStage.setTitle("Hello World"); primaryStage.setScene(new Scene(root, 300, 275)); primaryStage.show(); } public static void main(String[] args) { launch(args); } } 

而我的pom.xml也不算太大:

   4.0.0 sample JavaFXDemo 1.0-SNAPSHOT jar  RubberDucky      com.zenjava javafx-maven-plugin 2.0      com.zenjava javafx-maven-plugin 2.0  sample.Main       com.oracle javafx 2.2 ${java.home}/lib/jfxrt.jar system    

我正在使用JavaFX Maven插件来构建应用程序。 运行mvn clean jfx:jar一切似乎都很好,所有构建都成功了。 但是当我尝试运行应用程序时,我收到以下错误:

 Exception in Application start method java.lang.reflect.InvocationTargetException at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at com.javafx.main.Main.launchApp(Main.java:698) at com.javafx.main.Main.main(Main.java:871) Caused by: java.lang.RuntimeException: Exception in Application start method at com.sun.javafx.application.LauncherImpl.launchApplication1(Unknown So urce) at com.sun.javafx.application.LauncherImpl.access$000(Unknown Source) at com.sun.javafx.application.LauncherImpl$1.run(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.NullPointerException: Location is required. at javafx.fxml.FXMLLoader.load(Unknown Source) at javafx.fxml.FXMLLoader.load(Unknown Source) at javafx.fxml.FXMLLoader.load(Unknown Source) at javafx.fxml.FXMLLoader.load(Unknown Source) at javafx.fxml.FXMLLoader.load(Unknown Source) at sample.Main.start(Main.java:15) at com.sun.javafx.application.LauncherImpl$5.run(Unknown Source) at com.sun.javafx.application.PlatformImpl$5.run(Unknown Source) at com.sun.javafx.application.PlatformImpl$4$1.run(Unknown Source) at com.sun.javafx.application.PlatformImpl$4$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at com.sun.javafx.application.PlatformImpl$4.run(Unknown Source) at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source) at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) at com.sun.glass.ui.win.WinApplication.access$100(Unknown Source) at com.sun.glass.ui.win.WinApplication$3$1.run(Unknown Source) ... 1 more 

经过一些粗略的调试后,问题似乎出现在我从中加载文件的路径中。 将sample.fxml硬编码到硬盘驱动器上的某个位置后,应用程序运行没有任何问题。 从IntelliJ运行应用程序时,当前设置(如上所示)也是如此。

我觉得我已经耗尽了所有资源(包括StackOverflow,一些非常类似的错误),但我无法弄清楚到底出了什么问题。

确保sample.fxml位于src/main/resources/目录(或子目录)中。 然后你可以像这样访问文件:

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

说明 :在编译阶段,所有资源和类都被复制到target/classes/ 。 因此,您的fxml文件驻留在此目录中,并且您的类位于与其包名称相关的子目录中。 如果你调用getClass().getResource("sample.fxml"); 将相对于将成为此目录的类文件搜索该文件: target/classes/sample/

在类加载器上调用.getResource()设置target/classes/的相对搜索路径,从而找到您的文件。

PS你也可以写:

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

正如@ Absurd-Mind已经解释过的那样,maven不会复制位于src目录下的任何资源文件(如fxml)。

如果要保留除java源文件之外的fxml文件,可以使用maven资源插件来复制它们:

  ...   false src/main/java  **/*.fxml    ...  

我和Intelij和Gradle有同样的问题:修复步骤:

1.移动文件

sample.fxml

路径

\ SRC \主\资源\ FXML

  1. 在此文件上设置路径:

父root = FXMLLoader.load(getClass()。getResource(“/ fxml / sample.fxml”));

对于那些使用gradle作为构建系统的人,将其添加到build.gradle文件中:

 sourceSets.main.resources { srcDirs = ["src/main/java"]; //assume that your java classes are inside this path exclude "**/*.java" } 

然后清理并重建您的项目。

那会是什么呢? 如果你的com.example.myfxapp包中有view.fxml ,那么在构建你的项目之后它会导出到/resources/com/example/myfxapp/view.fxml

对我来说,我照顾过以下事情 –

  1. 确保将fxml文件放在主类所在的位置。 然后使用它加载它 – (在我的情况下,TechJFX.fxml是文件)

     FXMLLoader loader = new FXMLLoader(getClass().getResource("TechJFX.fxml")); 
  2. 将opencv – * .jar添加到项目文件夹中(在我的情况下为opencv-300.jar)

  3. 使用jar将jar添加到构建路径

右键单击项目文件夹 – >构建路径 – >配置构建路径 – >库选项卡 – >添加外部JARS并找到jar

此外,在订单和导出下 – >勾选opencv-300.jar和JRE系统库(如果尚未勾选)

  1. 将opencv_java * .dll(在我的情况下为opencv_java300.dll)复制到jar所在的项目文件夹中。

  2. 将以下方法添加到主类

      static{ System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } 
  3. 完成。

希望这有助于面临类似问题的人。