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

使用资源文件夹在使用IntelIiJ的JavaFX项目上加载图像,java,image,javafx,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 javaf

我正在尝试将图像加载到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的文件夹,并调用image
Main.class.getResource()
在项目根目录下创建一个名为
resources
的新目录(与
src
的层次结构相同)。在intellij中右键单击它,将其转换为源目录:
右键单击->将目录标记为->源根目录
。然后,如果愿意,您可以将资源文件组织到包中,就像在
src
中创建包一样。在这种情况下,您可以使用
资源/sample/nfc.png
。在您的代码中,您可以按如下方式加载它:

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

不用说,您需要添加错误处理代码,更喜欢使用
尝试使用资源

查找图像的快速解决方案

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

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

在项目基于构建工具(如maven)时查找图像

如果您使用的是Maven或Gradle等构建工具(建议用于任何中大型项目),那么它将有一个窗口,其中您的java类位于
src/main/java
中,而您的资源(如css和图像)位于
src/main/resources
中。它被自动配置为将资源复制到应用程序工件中

使用IntelliJ或其他IDE查找图像

您注意到,您使用的是IntelliJ,该工具(以及任何其他主要的Java IDE)足够智能,可以识别出使用构建工具(如maven)构建的项目具有标准结构,并且将在Idea中自动配置导入的maven项目以理解该结构,因此您不必做任何其他事情

如果您没有使用推荐的工具(如maven),则可以手动配置项目以在资源上进行复制(如图所示)。在其他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 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);
关于显式使用
文件的注意事项:
协议(不要这样做)

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

故障排除

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

System.out.println(getClass().getResource("<imagepath>"))
如果使用,则错误可能会异步发生,因此需要监视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());
        }
    });
}

我认为您缺少的步骤可能是确保资源文件夹位于classpath-Class中。getResource()将加载相对于用于调用该方法的类的资源,或者从类路径中可以找到的“绝对”路径加载资源。(也许你会看到)。在Maven中,默认情况下src/main/resources的内容放在类路径中-您必须检查InteliJ的行为…对于任务栏图像,您可能可以用JavaFX代码替换
awt
代码。
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());
        }
    });
}