JAVAFX:未设置位置错误[重复]

Posted

技术标签:

【中文标题】JAVAFX:未设置位置错误[重复]【英文标题】:JAVAFX: Location is not set error [duplicate] 【发布时间】:2016-04-17 18:35:21 【问题描述】:

我的项目在 Eclipse 中运行正常,但是当我创建该项目的 jar 文件并尝试通过 cmd 运行它时,它显示“未设置位置”错误。

我的项目结构是:

方法是(在eclipse中运行):

@FXML
private void RegularCustomer(ActionEvent event) throws Exception
    Stage stage = (Stage) dailySales.getScene().getWindow();
    Scene scene = dailySales.getScene();
    FXMLLoader loader = new FXMLLoader(getClass().getResource("../customer/CustomerHome.fxml"));
    System.out.println(loader.getLocation());
    scene.setRoot(loader.load());
    stage.setScene(scene);
    stage.show();

这段代码有什么问题?

有一些相关的问题,但它们与它不同。他们的代码没有在 IDE 中运行,但我的代码在 IDE 中运行。

仅供参考:我对文件夹结构进行了一些更改,并且能够成功运行。但这种结构很糟糕,因为我将所有 FXML 文件和控制器放在同一个包中。

【问题讨论】:

@jewelsea 虽然承认在 SO/javafx 上有很多这样的问题,(我在搜索时永远找不到它们)该问题的答案都没有真正解决这里的确切问题(我'将解释为“为什么这适用于文件系统类加载器但不适用于 jar 类加载器”,我认为它真的更接近***.com/questions/13046150)。有人可能应该写一个包罗万象的“如何在 JavaFX 中加载资源”Q/A,因为它似乎会导致很多问题...... 【参考方案1】:

当您使用getClass().getResource(...) 时,您正在加载资源,而不是指定文件的路径。在类加载器从文件系统加载类的情况下,这些本质上等同于同一件事,并且它确实有效(尽管即使那样也没有技术原因它必须这样做)。当类加载器通过其他机制加载类时(可能在所有情况下都可能),那么注意 Java specifications for a resource 是很重要的。

特别注意:

资源、名称和上下文

一个资源由一个字符串标识,该字符串由一系列 子字符串,由斜杠 (/) 分隔,后跟资源名称。 每个子字符串都必须是有效的 Java 标识符。 资源名称的格式为 shortName 或 shortName.extension。两者都是短名称 和 extension 必须是 Java 标识符。

(我强调。)由于.. 不是有效的Java 标识符,因此不能保证此资源是可解析的。碰巧文件系统类加载器以您期望的方式解决了这个问题,这就是它在您的 IDE 中工作的原因,但是 jar 类加载器中 getResource(...) 的实现并没有以您希望的方式实现这一点。

试试

FXMLLoader loader = new FXMLLoader(getClass().getResource("/sm/customer/CustomerHome.fxml"));

使用控制器位置加载 FXML:

由于您已经组织了代码,以便每个 FXML 与其对应的控制器文件位于同一个包中(我认为这是一种明智的做法),您还可以在加载 FXML 时利用它:只需加载 FXML “相对于它的控制器”:

FXMLLoader loader = new FXMLLoader(CustomerHomeCtrl.class.getResource("CustomerHome.fxml"));

在此设置中这似乎很自然,编译器将在您导入类时检查您的 CustomerHomeCtrl 的包名称是否正确。它还使重构变得容易:例如,假设您想将sm.admin 拆分为多个子包。在 Eclipse 中,您将创建子包,将 FXML 和控制器拖放到适当的子包中,导入语句将自动更新:不需要进一步的更改。在getResource(...) 中指定路径的情况下,所有这些都必须手动更改。

【讨论】:

为什么没有意义?相对路径是相对于类的包的。 感谢您提供的出色解决方案。它现在运行良好。 @Puce 更新了答案,使其更加精确。如果这更有意义,会感兴趣吗? 好吧,恕我直言,真正的问题是您操作的文件系统。原生文件系统支持“..”,而 jar 文件系统不支持 @tomsontom 我想我的意思是有一个独立于文件系统的资源命名行为规范。只要您的资源名称符合该规范,无论应用程序如何部署,它都可以正常工作。 (理论上,即使底层文件系统的要求比资源命名规范更严格。)【参考方案2】:

有点晚了,但这可能对某人有所帮助。如果您使用的是 IntelliJ,您的 resources 文件夹可能不会被标记为资源文件夹,该文件夹具有以下图标:

这是我修复它的方式:

【讨论】:

以上是关于JAVAFX:未设置位置错误[重复]的主要内容,如果未能解决你的问题,请参考以下文章

JavaFx 元素未绑定到 fx:id 上的控制器变量 [重复]

在 java 13 中找不到模块 javafx.base [重复]

使用教程中的 Javafx 类对游戏进行编程并遇到未定义的类错误

未捕获的类型错误:无法设置未定义的属性 [重复]

无法在 javafx 中链接 fxml 和控制器文件变量 [重复]

“对象引用未设置为对象的实例”我遇到了这个错误,我不知道为啥[重复]