JavaFX“需要位置”。即使它在同一个包中

Posted

技术标签:

【中文标题】JavaFX“需要位置”。即使它在同一个包中【英文标题】:JavaFX "Location is required." even though it is in the same package 【发布时间】:2013-12-28 17:52:02 【问题描述】:

我正在尝试让我的 JavaFX 程序运行,但遇到了一些困难。我不断收到“java.lang.NullPointerException:需要位置”的错误。 fxml 文件与 Application 类在同一个包中。这是我非常简单的代码:

package com.kromalights.designer.entry;

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
        Parent root = FXMLLoader.load(getClass().getResource("main.fxml"));
        primaryStage.setTitle("Kromalights Designer");
        primaryStage.setScene(new Scene(root, 300, 275));
        primaryStage.show();
    


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

这是我的 main.fxml 文件的副本:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.BorderPane?>
<?scenebuilder-stylesheet mailStyles.css?>
<?import java.net.*?>

<BorderPane prefHeight="300.0" prefWidth="300.0" xmlns:fx="http://javafx.com/fxml/1"
        xmlns="http://javafx.com/javafx/2.2"
        fx:controller="com.kromalights.designer.entry.Controller">
    <bottom>
        <Pane prefHeight="200.0" prefWidth="200.0"/>
    </bottom>
    <center>
        <Pane prefHeight="200.0" prefWidth="200.0"/>
    </center>
    <left>
        <VBox prefHeight="200.0" prefWidth="100.0"/>
    </left>
    <top>
        <HBox prefHeight="100.0" prefWidth="200.0"/>
    </top>
    <stylesheets>
        <URL value="@mainStyles.css" />
    </stylesheets>
</BorderPane>

控制器类确实存在并且在 fxml 文件中指定的包中。我所有的名字都是正确的,并且是我认为应该在的地方。我错过了什么?我确实尝试重命名我的 fxml 文件,以防出现名称问题。请帮忙。仅供参考,我在 OSX 上使用 Intellij IDEA。

更新:这是一个 Maven 问题。我为这个项目设置了 Maven,这导致了这个问题。我暂时删除了 Maven,这样我就可以在没有它的情况下继续工作。有没有人知道我在使用 Maven 时如何最好地处理这个问题?

【问题讨论】:

mainStyles.css 在哪里?它是否也与您的 FXML 和主应用程序类位于同一路径位置? 是的。这不是我的问题。如果我从我的 xml 文件中删除样式表信息,它仍然无法运行。这是我认为可能是问题的第一件事,所以我在没有样式表的情况下对其进行了测试。 因此,在 Maven 环境中,您的 fxml 必须转到 main/resources,否则它将获取运行时类路径的一部分。检查你从 getResource("main.fxml) 得到什么,我认为你从中得到 null! 【参考方案1】:

将文件移动到 main/resources 目录有效。

【讨论】:

我还必须使用Parent root = FXMLLoader.load(getClass().getResource("/fxml/Scene.fxml")); @OldCurmudgeon 的评论对于它的工作至关重要,需要将 .fxml 文件移动到 resources/fxml 文件夹。如果fxml 文件夹不存在,请创建它。 每次我开始一个新项目时,我都必须回到这篇文章,这是第一个有效的评论,可以挽救我的理智。是的,resources/fxml/Scene.fxml.getResource("/fxml/Scene.fxml") 像往常一样成功了。 嗨。我有一个类似的问题,但我无法解决它。我在这里问了一个问题,也许有人可以帮助我。正如您所说,我还尝试创建 /fxml 文件夹:***.com/questions/47939908/… 如建议的那样,如果它在资源中,它将通过在“/file.fxml”之前添加一个斜杠来工作,但我想添加一件事,因为我包含在我的项目 module-info.java 文件中我在其中指定要打开的包以及从完整依赖项中导入的内容。当我删除该文件时,这个斜杠和资源文件夹技术不起作用。您必须拥有该模块文件才能使其再次工作。【参考方案2】:

如果您的项目是基于 Maven 的,Idea 将忽略 src/main/java 文件夹中除 java 文件之外的所有文件。就像你说的将文件移动到 src/main/resources 是可行的,但现在 SceneBuilder 不再了解你的控制器类,因为它位于完全不同的目录中,你失去了所有的洞察力,你盲目地构建。

我相信这是 intellij 中的一个问题,因为 SceneBuilder EXPECTS 会在(我引用)“相同目录、直接子目录或 .fxml 的父目录中找到您的控制器类 java 文件" 文件。

【讨论】:

【参考方案3】:

我已经多次看到这个错误了。以至于我经常用 Netbeans Maven FXML 应用程序模板编写一个名为“Simple”的小项目,只是为了在出现问题时作为一种“参考模型”返回。对于测试,我使用这样的东西:

    String sceneFile = "/fxml/main.fxml";
    Parent root = null;
    URL    url  = null;
    try
    
        url  = getClass().getResource( sceneFile );
        root = FXMLLoader.load( url );
        System.out.println( "  fxmlResource = " + sceneFile );
    
    catch ( Exception ex )
    
        System.out.println( "Exception on FXMLLoader.load()" );
        System.out.println( "  * url: " + url );
        System.out.println( "  * " + ex );
        System.out.println( "    ----------------------------------------\n" );
        throw ex;
    

当您运行该 sn-p 并且加载失败时,您应该会看到一个原因,或者至少是来自 FXMLLoader 的一条消息。由于这是一个测试,我抛出异常。你不想继续了。

注意事项。这是一个 Maven 项目,因此资源将与资源文件夹相关,因此:

“/fxml/main.fxml”。 前导斜杠是必需的。

传递给 FXMLLoader 的资源区分大小写

// If you load "main.fxml" and your file is called: "Main.fxml"
// You will will see the message ...

java.lang.NullPointerException: Location is required.

如果您解决了“需要位置”问题,那么您可能在 FXML 中遇到问题

// 像这样: // javafx.fxml.LoadException: file:/D:/sandbox/javafx/app_examples/person/target/person-00.00.01-SNAPSHOT.jar!/fxml/tableWithDetails.fxml:13

意味着文件中的第 13 行有问题,根据:

tableWithDetails.fxml :13

在消息中。此时您需要阅读 FXML 并查看是否可以发现问题。您可以尝试相关问题中的一些提示。

对于这个问题,我认为文件名是正确的:“Main.fxml”。移动文件时,名称可能已更改或重新键入了字符串。祝你好运。

相关:

FXML / FXMLLoader error diagnostic tool(s) sought

【讨论】:

【参考方案4】:

我遇到了同样的错误。就我而言,fxml 文件名中有一个前导空格符号:

“fxml_example.fxml”而不是“fxml_example.fxml”

我不知道它是从哪里来的。很难注意到它。当我删除前导空格时,一切正常。我什至不知道文件名可以以空格符号开头。

【讨论】:

【参考方案5】:

就我而言,以上所有都不是问题。

更换后问题就解决了:

getClass().getResource("ui_layout.fxml")

与:

getClass().getClassLoader().getResource("ui_layout.fxml")

【讨论】:

这也为我解决了这个问题。有人知道为什么 getClassLoader() 会有所作为吗? 如果您使用的是IDE,问题可能是IDE不知道它需要在构建期间将.fxml文件复制到类文件旁边的输出目录中,这是getClass的位置().getResource() 将查找它(它不会在您的源代码树中查找!)。例如,如果您使用 IntelliJ,您可能需要在文件|设置|编译器设置中添加类似“;?.fxml;?.css”的内容,以告诉它在构建期间复制文件。请参阅***.com/questions/23421325/… 了解更多信息。 谢谢,这为我解决了类似的问题。我在 JavaFX 中创建 URL 以动态加载 FXML 文件。尝试了各种 IntelliJ 配置,我只需要这个简单的解决方案。【参考方案6】:

如果您的问题与 Maven 无关,并且您在浏览器中运行它时遇到相同的 NullPointerException(从 IDE 运行它很好),试试这个:

-> Netbeans -> 右键项目 -> 属性 -> 构建 -> 部署 -> 勾选“请求不受限制的访问(启用签名, 自签名)”

这是由于@FXML 注解需要权限才能注入 FXML 标记中的值(参见 http://docs.oracle.com/javafx/2/fxml_get_started/fxml_deployment.htm)

我在 JDK8u31 上运行我的应用程序,如果没有 Chrome / Firefox / IE 中的证书,它永远不会运行。

【讨论】:

它解决了我的问题。似乎存在与 fxml 文件相关的安全问题。如果你作为 jar 文件构建和运行良好,不要在 webstart 或浏览器中运行,试试这个方法。【参考方案7】:

此问题可能是由于 FXML 文件的路径不正确造成的。

如果您使用的是绝对路径 (my/package/views/view.fxml),则必须在前面加上一个斜杠:

getClass().getResource("/my/package/views/view.fxml")

您也可以使用相对路径:

getClass().getResource("views/view.fxml")

【讨论】:

【参考方案8】:

我有时也会遇到同样的异常。

当我在 Eclipse 中使用向导创建 FXML 文件时,我在名称字段中写入 example.fxml。 Eclipse 创建一个文件,例如 example.fxml.fxml。由于这个错误,FXMLLoader 无法找到正确的 FXML 文件。 因此,我的提示是,检查您的 start-Method 中 FXML-Filename 的名称和文件的真实名称。

希望我能提供帮助。祝你好运。

【讨论】:

【参考方案9】:
URL url = new File("src/main/java/ua/adeptius/goit/sample.fxml").toURI().toURL();
Parent root = FXMLLoader.load(url);

这对我有帮助,因为

getClass.getResource("path")

总是返回 null;

【讨论】:

toURL() 方法已被弃用。 我有完全相同的错误,无法弄清楚为什么它只能这样工作......我虽然问题来自 *.fxml 文件没有被复制到 out 目录,但显然它也可以在没有 ^^ 的情况下工作 更正解决方案。现在 toURL 已被弃用,然后变为: (path).toURI().toURL(); 谢谢,我真的尝试了一切,这似乎终于奏效了。 另一种可以尝试的方法 getClass().getClassLoader().getResource();或者我现在使用 FXMLLoader loader = new FXMLLoader(Gui.class.getResource("../../CrudService.fxml")); "../" - 表示父文件夹【参考方案10】:

我无法使用

getClass().getResource("views/view.fxml")

因为我将我的控制器类放入“控制器”包中,所以这是我的解决方案:

getClass().getResource("../views/view.fxml")

【讨论】:

这更像是对gronostaj's answer 的评论,而不是对原始问题的回答。 哦,对不起,我无法将 cmets 发布到某人的答案中,但也许它可以帮助像我这样的新手。但无论如何感谢您的澄清,这是真的。 我会避免使用..,因为部署的构建往往不知道如何使用该路径符号。相反,我做了一个绝对路径。【参考方案11】:

而不是

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

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

区别是“/”。

原因:

第一个:getResource 会尝试查找相对于包的资源

第二个:getResource 将其视为绝对路径并简单地调用类加载器。

【讨论】:

谢谢。另外,不要忘记使用新资源重建您的项目。在我的情况下,问题是由于这个。【参考方案12】:

加载程序的根目录位于 Maven 项目的“资源”文件夹中。因此,如果您有src/main/java,则 fxml 文件路径应从以下位置开始: src/main/resources

https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html

【讨论】:

【参考方案13】:

如果您查看文档 [1],您会发现 load() 方法可以采用 URL:

load(URL location)

因此,如果您运行的是 Java 7 或更高版本,则可以像这样加载 FXML 文件:

URL url = Paths.get("./src/main/resources/fxml/Fxml.fxml").toUri().toURL();
Parent root = FXMLLoder.load(url);

此示例来自一个 Maven 项目,这就是 FXML 文件位于资源文件夹中的原因。

[1]https://docs.oracle.com/javase/8/javafx/api/javafx/fxml/FXMLLoader.html

【讨论】:

更新链接 5 秒的搜索,找到了链接。 那对你来说太好了【参考方案14】:

我发现上述所有解决方案都可以正常工作,因为它们会触发您的 IDE 重新构建项目。不涉及魔法。

这个问题的“真正”解决方案是您应该放弃以前的构建目录。

如果您使用的是 Maven,只需删除目标文件夹(或执行 mvn clean)! 如果您使用的是 ANT,请删除相应的文件夹(我认为它已被删除)! 如果您使用的是 Gradle,请删除构建文件夹!

【讨论】:

【参考方案15】:

我尝试了上述答案,但在我的项目中不起作用。我的项目是在 Windows 中使用 mavenopenjfx

这解决了问题:

FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/main.fxml"));
root = fxmlLoader.load()

【讨论】:

【参考方案16】:

你应该在你的根目录中使用getClassLoader() 方法

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

【讨论】:

【参考方案17】:

2021 年 6 月:

将项目转换为 Maven 后,您应该将 fxml 和 css 文件移动到资源文件夹。只需拖放(在 IntelliJ 社区中)。然后:

Parent root = FXMLLoader.load(Objects.requireNonNull(getClass().getClassLoader().getResource("FXMLDocument.fxml")));

和:

 root.getStylesheets().add(getClass().getResource("/newCascadeStyleSheet.css").toString());
    

样式表需要斜线。

就是这样。

【讨论】:

以上是关于JavaFX“需要位置”。即使它在同一个包中的主要内容,如果未能解决你的问题,请参考以下文章

即使在eclipse中安装javafx后我也无法运行javafx程序[重复]

即使由于在另一个选项卡中而不可见,如何使 JavaFX 的 webview 呈现?

JavaFX LineChart 悬停值

如何使 JavaFX 控件居中

缺少 JavaFX 运行时组件,即使我的 VM 选项和模块中已经有了它们

什么是 JavaFX 运行时?