eclipse JAVAFX:位置未设置错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/34755630/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 23:00:26  来源:igfitidea点击:

JAVAFX: Location is not set error

javaeclipsejavafxjavafx-8

提问by Shihab

My project is running properly in eclipse but when I am creating a jar file of this project and trying to run it through cmd it is showing "Location is not set" error.

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

My project structure is:

我的项目结构是:

This is the structure of my project

这是我项目的结构

The Method is (Running in eclipse):

方法是(在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();
}

What is wrong with this code?

这段代码有什么问题?

There are some relative questions but they are different from it. Their code didn't run in IDE but my code run in IDE.

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

FYI: I made some changes in folder structure and was able to run successfully. But that structure was horrible because I put all my FXML files and controllers in same package.

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

回答by James_D

When you use getClass().getResource(...)you are loading a resource, not specifying a path to a file. In the case where the class loader loads classes from the file system, these essentially equate to the same thing, and it does actually work (though even then there's no technical reason it has to). When the class loader is loading classes by other mechanisms (and probably in all cases anyway), then it's important to pay attention to the Java specifications for a resource.

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

In particular, note:

特别要注意:

Resources, names, and contexts

A resource is identified by a string consisting of a sequence of substrings, delimited by slashes (/), followed by a resource name. Each substring must be a valid Java identifier.The resource name is of the form shortName or shortName.extension. Both shortName and extension must be Java identifiers.

资源、名称和上下文

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

(My emphasis.) Since ..is not a valid Java identifier, there's no guarantee of this resource being resolvable. It happens that the file system class loader resolves this in the way you expect, which is why it works in your IDE, but the implementation of getResource(...)in the jar class loader does not implement this in the way you are hoping.

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

Try

尝试

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


Using controller locations to load FXML:

使用控制器位置加载 FXML:

Since you have organized your code so that each FXML is in the same package as its corresponding controller file (which I think is a sensible way to do things), you could also leverage this in loading the FXML: just load the FXML "relative to its controller":

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

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

This seems fairly natural in this setup, and the compiler will check that you have the package name for CustomerHomeCtrlcorrect at the point where you import the class. It also makes it easy to refactor: for example suppose you wanted to split sm.admininto multiple subpackages. In Eclipse you would create the subpackages, drag and drop the FXML and controllers to the appropriate subpackages, and the import statements would automatically be updated: there would be no further changes needed. In the case where the path is specified in the getResource(...), all those would have to be changed by hand.

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