我的项目在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文件和控制器放在同一个包中。
答案 0 :(得分:15)
使用getClass().getResource(...)
时,您正在加载资源,而不是指定文件的路径。在类加载器从文件系统加载类的情况下,这些基本上等同于同一个东西,它确实起作用(尽管那时它没有技术原因)。当类加载器通过其他机制加载类时(并且可能在所有情况下都是如此),那么关注Java specifications for a resource是很重要的。
特别注意:
资源,名称和背景
资源由一个由一系列序列组成的字符串标识 子字符串,由斜杠(/)分隔,后跟资源名称。 每个子字符串必须是有效的Java标识符。 资源名称的格式为shortName或shortName.extension。两个shortName 和扩展必须是Java标识符。
(我的重点。)由于..
不是有效的Java标识符,因此无法保证此资源可解析。碰巧文件系统类加载器以您期望的方式解析它,这就是它在IDE中工作的原因,但是jar类加载器中getResource(...)
的实现并没有以您希望的方式实现它。
尝试
FXMLLoader loader = new FXMLLoader(getClass().getResource("/sm/customer/CustomerHome.fxml"));
由于您已经组织了代码,以便每个FXML与相应的控制器文件位于同一个包中(我认为这是一种明智的方法),您也可以在加载FXML时利用它:只需加载FXML "相对于其控制器":
FXMLLoader loader = new FXMLLoader(CustomerHomeCtrl.class.getResource("CustomerHome.fxml"));
在此设置中,这似乎相当自然,编译器将检查您在导入类时是否正确CustomerHomeCtrl
的包名称。它还使重构变得容易:例如,假设您想将sm.admin
拆分为多个子包。在Eclipse中,您将创建子包,将FXML和控制器拖放到相应的子包中,并且import语句将自动更新:不需要进一步更改。如果在getResource(...)
中指定了路径,那么所有这些都必须手动更改。
答案 1 :(得分:0)