使用资源文件夹通过IntelIiJ在JavaFX项目上加载图像

时间:2019-12-06 18:36:09

标签: java image javafx

我正在尝试将图像加载到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()

2 个答案:

答案 0 :(得分:3)

查找图片的快速解决方案

您将看到如何通过提供字符串"/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或其他位置,例如在远程网络上,因此访问它们所需的协议可能会更改(需要使用jar: protocol,而不是file:协议访问jar中的文件)。如果您没有在Image构造函数中指定协议,则系统将默认使用类加载器,该类加载器已经知道要使用哪种协议在您的类路径上查找资源。

问题排查

在您要加载图像的代码中放置以下行:

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

"<imagepath>"的位置与您传递给图像构造器的字符串完全相同。如果呼叫输出null,则图像可能不在您预期的位置的班级路径上。

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

图像具有errorexception属性,如果无法加载,您可以查询该异常,它可以为您提供更多有关错误原因的信息,例如:

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

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

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());
        }
    });
}

答案 1 :(得分:1)

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

resources/sample/nfc.png

不用说,您需要添加错误处理代码,更喜欢使用new Image(this.getClass().getResourceAsStream("nfc.png"));

相关问题