使用资源文件夹在使用 IntelLiJ 的 JavaFX 项目上加载图像

Posted

技术标签:

【中文标题】使用资源文件夹在使用 IntelLiJ 的 JavaFX 项目上加载图像【英文标题】:Using a resource folder to load images on JavaFX project using IntelIiJ 【发布时间】:2020-03-31 18:26:06 【问题描述】:

我正在尝试将图像加载到 JavaFX 项目。我通过调用绝对路径Users/user/Desktop/nfc.png 来做到这一点。有没有办法在项目中创建资源文件夹并从中调用图像?

下面是我的代码:

package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;

import java.awt.Taskbar;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;



public class Main extends Application 

    @Override
    public void start(Stage primaryStage) throws Exception
        Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));

        primaryStage.setResizable(false);

        Scene scene = new Scene(root);

        scene.getStylesheets().add("/sample/desing.css");

        primaryStage.getIcons().add(new Image("file:/Users/user/Desktop/nfc.png "));



        primaryStage.setScene(scene);
        primaryStage.show();
    


    public static void main(String[] args)
    
        Taskbar taskbar=Taskbar.getTaskbar();
        BufferedImage image = null;
        try 
            image = ImageIO.read(new File("/Users/user/Desktop/nfc.png"));
         catch (IOException e) 
            e.printStackTrace();
        
        taskbar.setIconImage(image);
        launch(args);
    

我正在使用 IntelIJ。我尝试通过在项目目录上创建一个名为 resource 的文件夹并调用图像Main.class.getResource()

【问题讨论】:

我认为您缺少的步骤可能是确保您的资源文件夹位于您的类路径中 - Class.getResource() 将加载与用于调用该方法的类相关的资源,或者从可以在您的类路径中找到的“绝对”路径。 (也许见***.com/questions/6608795/…)。在 Maven 中,默认情况下 src/main/resources 的内容放在你的类路径中——你必须检查 InteliJ 的行为...... 对于任务栏图像,您可以将awt代码替换为JavaFX代码to set the application icon。 【参考方案1】:

查找图片的快速解决方案

您可以通过提供字符串"/sample/desing.css" 来查看如何在前一行中加载样式表,对您的图像执行相同的操作,例如new Image("/sample/nfc.png")

假设图像与您的 css 位于同一位置。如果它在其他地方,例如在/images/ngc.png 下,那么您将使用该路径。它还假设您的构建系统配置为将源资源文件复制到您的项目输出目录。

当您的项目基于构建工具(例如 maven)时查找图像

如果您使用的是 Maven 或 Gradle 等构建工具(推荐用于任何大中型项目),它将有一个 standard structure,其中您的 java 类位于 src/main/java 和您的资源,例如 css 和图片在src/main/resources。它会自动配置为将资源复制到您的应用程序工件中。

使用 IntelliJ 或其他 IDE 查找图像

您注意到您正在使用 IntelliJ,该工具(以及任何其他主要 Java IDE)足够智能,可以识别使用 maven 等构建工具构建的项目具有标准结构,并将自动配置导入的 maven 项目了解该结构的想法,因此您无需执行任何其他操作。

如果您没有使用推荐的工具,例如 maven,那么您可以手动配置项目以复制资源(如 @egimaben defined in his answer)。在其他 IDE 中复制资源的手动配置会有所不同,因此您需要研究 IDE 如何处理项目资源以找出如何为此类项目执行此操作。

查找图片的示例代码

例如,如果您的图像位于项目源中的此位置:src/main/resources/images/ngc.png,您可以通过以下方式在项目中访问它:

Image image = new Image("/images/nfc.png");

如果您不需要对图像的引用,则可以直接从 ImageView 构造函数中引用位置:

ImageView imageView = new ImageView("/images/nfc.png");

相关文档

阅读the image doc 了解如何找到图像。具体来说,这些行显示了如何从类路径上的资源加载图像:

// The image is located in default package of the classpath
Image image1 = new Image("/flower.png", true);

// The image is located in my.res package of the classpath
Image image2 = new Image("my/res/flower.png", 100, 150, false, false);

关于明确使用file: 协议的注意事项(不要这样做)

要从类或模块路径加载,不要显式使用file: 协议,您的文件可能位于 jar 或其他地方,例如远程网络上,因此访问它们所需的协议可能会更改(a jar 中的文件需要使用jar: protocol 访问,而不是file: 协议)。如果您没有在 Image 构造函数中指定协议,那么系统将默认使用类加载器,它已经知道使用什么协议在您的类路径上查找资源。

疑难解答

将以下行放在您尝试加载图像的代码中:

System.out.println(getClass().getResource("<imagepath>"))

"&lt;imagepath&gt;" 与您传递给图像构造器的字符串完全相同。如果调用输出null,则图像可能不在您的类路径中的预期位置。

如果您的应用程序打包为 jar,请运行 jar tvf &lt;yourjar&gt;.jar,将 &lt;yourjar&gt; 替换为您的 jar 文件的名称,它将列出 jar 文件中的所有内容。该图像很可能不在您尝试从中检索它的 jar 文件中的位置,因此您需要移动它或修复您的构建系统以将其放置在正确的位置。

图像具有error 和exception 属性,如果加载失败,您可以查询异常,它可能会为您提供更多错误信息,例如:

Image image = new Image("/images/nfc.png");
if (image.isError()) 
    System.out.println(image.getException());

如果您使用image constructor with background loading,则错误可能会异步发生,因此您需要监视错误属性中的更改以了解是否发生错误:

Image image = new Image("/images/nfc.png");
if (image.isError()) 
    System.out.println(image.getException());
 else 
    image.errorProperty().addListener((observable, oldValue, newValue) -> 
        if (image.isError()) 
            System.out.println(image.getException());
        
    );

【讨论】:

【参考方案2】:

在项目的根目录(与src 在同一层次结构中)创建一个名为resources 的新目录。通过在 intellij 中右键单击将其转换为源目录:Right click -&gt; Mark directory as -&gt; Sources Root。然后,您可以根据需要将资源文件组织到包中,就像在 src 中创建包一样。在这种情况下,您可以拥有resources/sample/nfc.png。在您的代码中,您可以按如下方式加载它:

new Image(this.getClass().getResourceAsStream("nfc.png"));

不用说,你需要添加错误处理代码,更喜欢使用try-with-resources

【讨论】:

以上是关于使用资源文件夹在使用 IntelLiJ 的 JavaFX 项目上加载图像的主要内容,如果未能解决你的问题,请参考以下文章

IntelliJ 没有看到资源文件夹

intellij idea无法将编译的class文件及新建的资源文件打进war包

在 IntelliJ for Maven 项目中添加资源

IntelliJ IDEA Ultimate项目加载问题

从 IntelliJ 在 Windows 资源管理器中打开包含目录

IntelliJ插件开发冻结目标IntelliJ实例