46

我正在创建一个 javafx GUI 应用程序,我的项目是一个 Maven 配置项目。我希望能够在我的控制器中引用我的 fxml 文件:

FXMLLoader.load(getClass().getResource("main.fxml"); 

我的 main.fxml 文件位于 src/main/resources 文件夹中,而我的控制器位于 src/main/java 文件夹中。我该怎么做呢?我的 src/main/resources 文件夹位于构建路径中,我可以从 src/main/java 文件夹中的类调用 src/main/resources 文件夹中的 .properties 文件。

编辑

我试图将 fxml 文件放在主资源文件夹的相应目录中:

在此处输入图像描述

但我仍然有一个错误。

4

3 回答 3

117

通用资源查找信息

这个答案讨论了 FXML 位置查找,它实际上只是 Java 中通用资源查找任务的一个子集。调用程序将资源位置作为输入传递给 FXMLLoader,因此资源查找本身是调用应用程序代码的一部分,而不是 FXMLLoader。

有关 Java/JavaFX 应用程序的通用资源信息(包括推荐的故障排除步骤)的全面介绍,请参阅:

伊甸园编码资源指南也很有用:


示例用法

FXMLLoader loader = new FXMLLoader();
loader.setLocation(getClass().getResource("/main.fxml"));
Parent content = loader.load(); 

位置分辨率选项

  1. 将所有 fxml 放在 src/main/resources 目录中。

    loader.setLocation(getClass().getResource("/main.fxml"));
    
  2. 将所有 fxml 放在 src/main/resources/fxml 目录中。

    loader.setLocation(getClass().getResource("/fxml/main.fxml"));
    
  3. 将fxml放在对应的资源目录中;例如 src/main/resources/com/mycompany/myapp。

    loader.setLocation(getClass().getResource("main.fxml")); 
    

最后一个选项假定您从中加载 fxml 的类位于相应 Java 源层次结构中的相同相对位置。例如,您可能会从 source 调用最后一个加载命令com/mycompany/myapp/Main.java

FXMLLoader 使用建议

  1. 通过new FXMLLoader()而不是使用 FXMLLoader 上的静态方法来实例化 FXMLLoader

  2. 在实例化的 FXMLLoader 上 设置位置load()并调用而不是使用 load(stream).

    • 在加载器上设置基于 URL 的位置允许解析在 fxml 和 css 文件中加载的相关资源。相对资源不会为基于流的构造函数解析。
  3. 要基于类派生位置,请使用 getClass().getResource(),因为它是基于 URL 的,而不是 getClass().getResourceAsStream()基于流的。

IDE 和构建设置

确保您的 IDE 或构建工具正在将 fxml 文件从资源目录复制到构建输出目录。要了解 Intellij 的设置,请参阅:如何将 intellij 中的普通 java 项目转换为 JavaFx 项目

关于 Java Jigsaw 模块化应用程序的说明

看:

具体来说,不要写:

ComboBoxStyling.class.getClassLoader()
    .getResource("/css/styleclass.css");

而是写:

ComboBoxStyling.class
    .getResource("/css/styleclass.css"); 

也就是说,直接从类中获取资源,而不是从类加载器中获取。如果您从类加载器而不是类中获取资源,那么基于模块配置的查找会有额外的限制。这些限制可能很难理解,如果需要,请参阅文档Class和方法以获取信息。ClassLoader getResource

于 2013-10-26T05:10:29.090 回答
8

您正在使用FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource("main.fxml") );加载您的 main.fxml。这需要将 main.fxml 和 java 类加载到相同的目录/路径中。如果要从与加载它的 java 类不同的路径/位置加载 fxml 文件,则需要使用相对路径。正如上面提到的@jewelsea,您可以在 main.fxml 之前使用 / 字符使用相对路径。因此,在您的情况下,使其为您工作的代码是

FXMLLoader fxmlLoader = new FXMLLoader( getClass().getResource("/main.fxml") );
于 2013-10-27T05:37:47.613 回答
0

在操作系统的文件资源管理器中打开资源文件夹。在这里,您将看到您创建了一个“dominion.application”文件夹,而不是“dominion”文件夹内的“application”文件夹。因此,“MainController”类与 fxml 文件放在不同的包中。

于 2013-11-19T09:59:11.090 回答