繁体   English   中英

使用 getClass().getResource() 加载资源

[英]Loading resources using getClass().getResource()

我正在尝试加载图像以在我的应用程序中用作图标。 根据本教程的适当方法是:

protected ImageIcon createImageIcon(String path, String description) 
{
    java.net.URL imgURL = getClass().getResource(path);
    if (imgURL != null) {
        return new ImageIcon(imgURL, description);
    } else {
        System.err.println("Couldn't find file: " + path);
        return null;
    }
}

所以,我放置了文件的位置,并将它作为参数传递给这个函数。 这不起作用,即 imgURL 为空。 当我尝试通过显式传入路径来创建 ImageIcon 时:

ImageIcon icon  = new ImageIcon(path,"My Icon Image");

它工作得很好! 因此,应用程序可以从明确定义的路径中选取图像,但不会使用 getResources() 选取图像。 在这两种情况下,路径变量的值是相同的。 为什么它不起作用? 类加载器如何找到资源?

谢谢。

getClass().getResource(path)从类getClass().getResource(path)加载资源,而不是从文件系统路径加载。

您可以请求以下格式的路径:

/package/path/to/the/resource.ext

甚至用于在内存中创建类的字节也是这样找到的:

my.Class -> /my/Class.class

getResource会给你一个 URL,可用于检索InputStream

但是...我建议直接使用getClass().getResourceAsStream(...)和相同的参数,因为它直接返回 InputStream 并且不必担心创建一个(可能很复杂)的 URL 对象,它必须知道如何创建 InputStream。

简而言之:尝试使用getResourceAsStream和一些使用InputStream作为参数的ImageIcon构造函数。

类加载器

如果您的应用程序有很多类加载器,请小心。 如果您有一个简单的独立应用程序(没有服务器或复杂的东西),您不必担心。 如果ImageIcon能够找到它,我认为情况并非如此。

编辑:类路径

getResource是——正如 mattb 所说——用于从类路径(从你的 .jar 或类路径目录)加载资源。 如果您正在捆绑一个应用程序,那么完全拥有它是很好的,因此您可以将图标文件包含在您的应用程序的 jar 中并通过这种方式获取它。

作为菜鸟,我对此感到困惑,直到我意识到所谓的“路径”是对于 MyClass 的路径。 class文件在文件系统中,而不是 MyClass。 java文件。 我的 IDE 将资源(如 xx.jpg、xx.xml)复制到 MyClass.class 的本地目录中。 例如,在名为“target/classes/pkg”的 pkg 目录中。不同 IDE 的类文件位置可能不同,具体取决于应用程序的构建结构。您应该首先浏览文件系统并找到MyClass.class 文件和您要提取的关联资源的复制位置。然后确定相对于 MyClass.class 文件的路径,并将其写为带有“点”和“斜线”的字符串值。

例如,这里是我如何使 app1.fxml 文件可用于我的 javafx 应用程序,其中相关的“MyClass.class”隐式为“Main.class”。 Main.java 文件是包含这行资源调用代码的地方。 在我的特定情况下,资源被复制到与封闭包文件夹相同级别的位置。 即:/target/classes/pkg/Main.class 和 /target/classes/app1.fxml。 所以解释...相对引用“../app1.fxml”是“从Main.class开始,上一级目录,现在你可以看到资源”。

FXMLLoader loader = new FXMLLoader();
        loader.setLocation(getClass().getResource("../app1.fxml"));

请注意,在此相对路径字符串“../app1.fxml”中,前两个点引用包含 Main.class 的目录和单个“.”。 表示要遵循的文件扩展名。 当这些细节成为第二天性之后,你就会忘记它为什么令人困惑。

通过示例获取资源:

package szb.testGetResource;
public class TestGetResource {
    private void testIt() {
        System.out.println("test1: "+TestGetResource.class.getResource("test.css"));
        System.out.println("test2: "+getClass().getResource("test.css"));
    }
    public static void main(String[] args) {
        new TestGetResource().testIt();
    }
}

在此处输入图片说明

输出:

test1: file:/home/szb/projects/test/bin/szb/testGetResource/test.css
test2: file:/home/szb/projects/test/bin/szb/testGetResource/test.css

getResourceAsStream() 查看您的资源文件夹内部。 因此,文件应放置在定义的资源文件夹内,即如果文件位于 /src/main/resources/properties --> 则路径应为 /properties/yourFilename。

getClass.getResourceAsStream(/properties/yourFilename)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM