JAVAFX:位置未设置错误

Dij*_*tra 5 java eclipse javafx javafx-8

我的项目在eclipse中正常运行但是当我创建这个项目的jar文件并尝试通过cmd运行时,它显示"Location not set set"错误.

我的项目结构是:

这是我项目的结构

方法是(在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();
}
Run Code Online (Sandbox Code Playgroud)

这段代码有什么问题?

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

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

Jam*_*s_D 16

使用时,getClass().getResource(...)您正在加载资源,而不是指定文件的路径.在类加载器从文件系统加载类的情况下,这些基本上等同于同一个东西,它确实有效(尽管那时它没有技术原因).当类加载器通过其他机制(并且可能在所有情况下)加载类时,重要的是要注意资源的Java 规范.

特别注意:

资源,名称和上下文

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

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

尝试

FXMLLoader loader = new FXMLLoader(getClass().getResource("/sm/customer/CustomerHome.fxml"));
Run Code Online (Sandbox Code Playgroud)

使用控制器位置加载FXML:

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

FXMLLoader loader = new FXMLLoader(CustomerHomeCtrl.class.getResource("CustomerHome.fxml"));
Run Code Online (Sandbox Code Playgroud)

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