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 类对游戏进行编程并遇到未定义的类错误