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 中使用 maven
和 openjfx
。
这解决了问题:
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 呈现?