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

时间:2014-02-24 22:23:17

标签: java maven javafx

我一直在尝试使用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也不算太大:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>sample</groupId>
    <artifactId>JavaFXDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <organization>
        <name>RubberDucky</name>
    </organization>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>com.zenjava</groupId>
                    <artifactId>javafx-maven-plugin</artifactId>
                    <version>2.0</version>
                </plugin>
            </plugins>
        </pluginManagement>
        <plugins>
            <plugin>
                <groupId>com.zenjava</groupId>
                <artifactId>javafx-maven-plugin</artifactId>
                <version>2.0</version>
                <configuration>
                    <mainClass>sample.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>javafx</artifactId>
            <version>2.2</version>
            <systemPath>${java.home}/lib/jfxrt.jar</systemPath>
            <scope>system</scope>
        </dependency>
    </dependencies>
</project>

我正在使用JavaFX Maven Plugin来构建应用程序。运行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,一些非常类似的错误),但我无法弄清楚到底出了什么问题。

6 个答案:

答案 0 :(得分:79)

确保您的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/,从而找到您的文件。

P.S。你也可以写:

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

答案 1 :(得分:8)

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

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

<build>
    ...
    <resources>
        <resource>
            <filtering>false</filtering>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.fxml</include>
            </includes>             
        </resource>
    </resources>
    ...
</build>

答案 2 :(得分:5)

我与Intelij和Gradle有同样的问题。

修复步骤:

1.移动文件

  

sample.fxml

到路径

  

\ SRC \主\资源\ FXML

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

    父root =   FXMLLoader.load(的getClass()的getResource(&#34; /fxml/sample.fxml"));

答案 3 :(得分:1)

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

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

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

那它会做什么?如果您的view.fxml包中有com.example.myfxapp,则在构建项目后,它将导出到<build dir>/resources/com/example/myfxapp/view.fxml

答案 4 :(得分:0)

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

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

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

  3. 使用

  4. 将jar添加到构建路径

    右键单击项目文件夹 - &gt;构建路径 - &gt;配置构建路径 - &gt;库标签 - &gt;添加外部JARS并找到jar

    此外,在订单和导出下 - &gt;勾选opencv-300.jar和JRE系统库(如果尚未勾选的话)

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

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

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

    4. 希望这可以帮助面临类似问题的人。

答案 5 :(得分:0)

我的案例是将Javafs SDK安装到C:\Program Files\Java\openjfx-11.0.2_windows-x64_bin-sdk

根本原因是sdk路径名中包含的空格。

通过将javafx sdk安装到名称中没有空格的文件夹来修复,例如C:\javafx-sdk-11.0.2\lib