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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2343187/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 06:23:20  来源:igfitidea点击:

Loading resources using getClass().getResource()

javaswing

提问by Luhar

I am trying to load an image to use as an icon in my application. The appropriate method according to this tutorialis:

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

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

So, I placed the location of the file, and passed it as a parameter to this function. This didn't work, i.e. imgURL was null. When I tried creating the ImageIcon by passing in the path explicitly:

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

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

It worked great! So the application can pick up the image from an explicitly defined path, but didn't pick up the image using getResources(). In both cases, the value of the path variable is the same. Why wouldn't it work? How are resources found by the class loader?

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

Thanks.

谢谢。

采纳答案by helios

You can request a path in this format:

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

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

Even the bytes for creating the classes in memory are found this way:

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

my.Class -> /my/Class.class

and getResourcewill give you a URL which can be used to retrieve an InputStream.

并且getResource会给你可以用来检索一个URL InputStream

But... I'd recommend using directly getClass().getResourceAsStream(...)with the same argument, because it returns directly the InputStream and don't have to worry about creating a (probably complex) URL object that has to know how to create the InputStream.

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

In short: try using getResourceAsStreamand some constructor of ImageIconthat uses an InputStreamas an argument.

简而言之:尝试 usinggetResourceAsStream并且它的一些构造函数ImageIcon使用 anInputStream作为参数。

Classloaders

类加载器

Be careful if your app has many classloaders. If you have a simple standalone application (no servers or complex things) you shouldn't worry. I don't think it's the case provided ImageIconwas capable of finding it.

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

Edit: classpath

编辑:类路径

getResourceis—as mattb says—for loading resources from the classpath (from your .jar or classpath directory). If you are bundling an app it's nice to have altogether, so you could include the icon file inside the jar of your app and obtain it this way.

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

回答by matt b

getClass().getResource(path)loads resources from the classpath, not from a filesystem path.

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

回答by J.E.Tkaczyk

As a noobie I was confused by this until I realized that the so called "path" is the path relativeto the MyClass.classfile in the file system and not the MyClass.javafile. My IDE copies the resources (like xx.jpg, xx.xml) to a directory local to the MyClass.class. For example, inside a pkg directory called "target/classes/pkg. The class-file location may be different for different IDE's and depending on how the build is structured for your application. You should first explore the file system and find the location of the MyClass.class file and the copied location of the associated resource you are seeking to extract. Then determine the path relative to the MyClass.class file and write that as a string value with "dots" and "slashes".

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

For example, here is how I make an app1.fxml file available to my javafx application where the relevant "MyClass.class" is implicitly "Main.class". The Main.java file is where this line of resource-calling code is contained. In my specific case the resources are copied to a location at the same level as the enclosing package folder. That is: /target/classes/pkg/Main.class and /target/classes/app1.fxml. So paraphrasing...the relative reference "../app1.fxml" is "start from Main.class, go up one directory level, now you can see the resource".

例如,这里是我如何使 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"));

Note that in this relative-path string "../app1.fxml", the first two dots reference the directory enclosing Main.class and the single "." indicates a file extension to follow. After these details become second nature, you will forget why it was confusing.

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

回答by SzB

getResource by example:

通过示例获取资源:

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

enter image description here

在此处输入图片说明

output:

输出:

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