Java 如何访问 JAR 文件中的资源?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2393194/
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:56:09  来源:igfitidea点击:

How to access resources in JAR file?

javaimageurlresourcesjar

提问by bcoughlan

I have a Java project with a toolbar, and the toolbar has icons on it. These icons are stored in a folder called resources/, so for example the path might be "resources/icon1.png". This folder is located in my src directory, so when it is compiled the folder is copied into bin/

我有一个带有工具栏的 Java 项目,工具栏上有图标。这些图标存储在名为 resources/ 的文件夹中,因此例如路径可能是“resources/icon1.png”。这个文件夹位于我的 src 目录中,所以当它被编译时,文件夹被复制到 bin/

I'm using the following code to access the resources.

我正在使用以下代码访问资源。

    protected AbstractButton makeToolbarButton(String imageName, String actionCommand, String toolTipText,
        String altText, boolean toggleButton) {

    String imgLocation = imageName;
    InputStream imageStream = getClass().getResourceAsStream(imgLocation);

    AbstractButton button;
    if (toggleButton)
        button = new JToggleButton();
    else
        button = new JButton();

    button.setActionCommand(actionCommand);
    button.setToolTipText(toolTipText);
    button.addActionListener(listenerClass);

    if (imageStream != null) { // image found
        try {
            byte abyte0[] = new byte[imageStream.available()];
            imageStream.read(abyte0);

            (button).setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(abyte0)));

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                imageStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } else { // no image found
        (button).setText(altText);
        System.err.println("Resource not found: " + imgLocation);
    }

    return button;
}

(imageName will be "resources/icon1.png" etc). This works fine when run in Eclipse. However, when I export a runnable JAR from Eclipse, the icons are not found.

(imageName 将是“resources/icon1.png”等)。这在 Eclipse 中运行时工作正常。但是,当我从 Eclipse 导出可运行的 JAR 时,找不到图标。

I opened the JAR file and the resources folder is there. I've tried everything, moving the folder, altering the JAR file etc, but I cannot get the icons to show up.

我打开了 JAR 文件,资源文件夹就在那里。我已经尝试了所有方法,移动文件夹,更改 JAR 文件等,但我无法显示图标。

Does anyone know what I'm doing wrong?

有谁知道我做错了什么?

(As a side question, is there any file monitor that can work with JAR files? When path problems arise I usually just open FileMon to see what's going on, but it just shows up as accessing the JAR file in this case)

(作为一个附带问题,是否有任何文件监视器可以处理 JAR 文件?出现路径问题时,我通常只是打开 FileMon 来查看发生了什么,但在这种情况下它只是显示为访问 JAR 文件)

Thank you.

谢谢你。

采纳答案by Christian

To load an image from a JAR resource use the following code:

要从 JAR 资源加载图像,请使用以下代码:

Toolkit tk = Toolkit.getDefaultToolkit();
URL url = getClass().getResource("path/to/img.png");
Image img = tk.createImage(url);
tk.prepareImage(img, -1, -1, null);

回答by Michael Borgwardt

I see two problems with your code:

我发现您的代码有两个问题:

getClass().getResourceAsStream(imgLocation);

This assumes that the image file is in the same folder as the .class file of the class this code is from, not in a separate resources folder. Try this instead:

这假设图像文件与此代码来自的类的 .class 文件位于同一文件夹中,而不是位于单独的资源文件夹中。试试这个:

getClass().getClassLoader().getResourceAsStream("resources/"+imgLocation);

Another problem:

另一个问题:

byte abyte0[] = new byte[imageStream.available()];

The method InputStream.available()does notreturn the total number of bytes in the stream! It returns the number of bytes available without blocking, which is often much less.

该方法InputStream.available()不会返回流中的字节总数!它返回无阻塞可用的字节数,通常要少得多。

You have to write a loop to copy the bytes to a temporary ByteArrayOutputStreamuntil the end of the stream is reached. Alternatively, use getResource()and the createImage()method that takes an URL parameter.

您必须编写一个循环来将字节复制到临时文件,ByteArrayOutputStream直到到达流的末尾。或者,使用带有 URL 参数getResource()createImage()方法。

回答by camickr

The section from the Swing tutorial on How to Use Iconsshows you how to create a URL and read the Icon in two statements.

Swing 教程中关于如何使用图标的部分向您展示了如何在两个语句中创建 URL 和读取图标。

回答by Alain Demortier

For example in a NetBeans project, create a resources folder in the src folder. Put your images (jpg, ...) in there.

例如,在 NetBeans 项目中,在 src 文件夹中创建一个资源文件夹。将您的图像(jpg,...)放在那里。

Whether you use ImageIO or Toolkit (including getResource), you must include a leading / in your path to the image file:

无论您使用 ImageIO 还是 Toolkit(包括 getResource),您都必须在图像文件的路径中包含一个前导 /:

Image image = Toolkit.getDefaultToolkit().getImage(getClass().getResource("/resources/agfa_icon.jpg"));
setIconImage(image);

If this code is inside your JFrame class, the image is added to the frame as an icon in your title bar.

如果此代码位于 JFrame 类中,则图像将作为标题栏中的图标添加到框架中。