Java资源图片未显示。

3
我一直在尝试将图像资源显示在我正在开发的GUI上,但是我很难让它们显示出来。我遇到了其他关于加载资源的问题,例如java-swing-displaying-images-from-within-a-jarimages-will-not-work-in-a-jar-file,但它们对我不起作用。
我的问题似乎与第一个链接相同,在Eclipse中运行时图像出现,在使用Jars从命令行运行时图像不会出现。然而,这些问题的解决方案并没有使图像出现。
我检索资源的代码如下:
public class R {

    public static final String resourcePackage = "path/to/image/package";

    /**
     * Returns the resource string that refers to the <code>resource</code> file
     * in the <code>path.to.image.package.png</code> package.
     * 
     * @param resource
     *            the file in the <code>png</code> package
     * @return the full resource string
     */
    public static String png(String resource) {
        return String.format("%s/png/%s", resourcePackage, resource);
    }

    public static ResizableIcon resizableIcon(String resource) {
        return ImageWrapperResizableIcon.getIcon(R.class.getClassLoader()
            .getResourceAsStream(resource), new Dimension(48, 48));
    }
}

我在生成GUI时调用它

JCommandButton connect = new JCommandButton(i18ln.getString("ports"),
                R.resizableIcon(R.png("serial-port-32x32.png")));

一条打印语句表明已找到资源,因为R.class.getClassLoader().getResourceAsStream返回sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream的实例。
我被难住了。我已经花了几个小时试图解决这个问题,但还需要帮助。有什么想法吗?
FYI:我不认为这很重要,但我正在使用Flamingo作为我的GUI。
编辑:按照Stefan的请求
src /
    main /
        java /
            com.company.project(包)
                R.java
                MyGui.java
        资源 /
            com.company.project(包)
                .png(包)
                    serial-port-32x32.png
                    (更多图像)
                .i18ln(包)
                    MyGui.properties
至于更多代码,我不知道我能提供什么其他有益于这个问题的东西。我提供了检索资源以及如何使用该代码的所有代码。您是否在寻找特定的内容?
更新:
当我使用Eclipse创建Jar并从命令行运行时,图像资源会正确显示。但是当我使用Gradle创建Jar时,图像不会显示。因此,在生成Jars时有些不同的事情被做了,这使得通过Eclipse Jar可以正确访问图像资源,而不是Gradle Jar。我在Gradle论坛上就这个问题提出了一个问题

你检查过图像是否实际上在JAR中了吗? - Garrett Hall
@E-rich:在使用Eclipse时,您是否创建了一个“源文件夹”来放置图像?如果没有,请看看我的答案,它可能会指导您完成。 - nIcE cOw
5个回答

3

根据你的应用所处的环境(独立运行,应用服务器),你需要使用适当的ClassLoader

如果你有一个实用工具类Utils,你可以尝试以下代码:

/* Returns a instance of InputStream for the resource */
public static InputStream getResourceAsStream(String resource) 
                                                   throws FileNotFoundException {
    String stripped = resource.startsWith("/")?resource.substring(1):resource;
    InputStream stream = null;
    ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
    if (classLoader != null) {
        stream = classLoader.getResourceAsStream(stripped);
    }
    if (stream == null) {
        stream = Utils.class.getResourceAsStream(resource);
    }
    if (stream == null) {
        stream = Utils.class.getClassLoader().getResourceAsStream(stripped);
    }
    if (stream == null) {
        throw new FileNotFoundException("Resource not found: " + resource);
    }
    return stream;
}

使用方法:

Utils.getResourceAsStream("com/company/project/png/serial-port-32x32.png");

看起来很有希望。在Eclipse中工作,但从命令行中不工作。从命令行中,它返回一个sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream实例。但是然后它抛出了一个javax.imageio.IIOException: Error reading PNG image data - E-rich
javax.imageio.IIOException: Error reading PNG image data 不是根本原因。 - Paul Vargas

2

src/main/javasrc/main/resources都是Eclipse中的源文件夹。在Eclipse中一切正常,问题出现在我将所有内容打成jar包并从命令行运行后。.java文件和所有资源文件都包含在**.jar**文件中,但图片却无法显示。 - E-rich
是的,这是因为它们所在的位置,所以按照我在那个链接中告诉你的步骤去做,这样你就可以运行带有图像的.jar文件了。在Eclipse中,src不是你的“源文件夹”,你需要自己创建它,用斜杠“/”访问“应用程序资源”。 - nIcE cOw
我收到了一个 javax.imageio.IIOException: Error reading PNG image data 异常。我还没有找到关于这个错误的有用信息。 - E-rich
你确定你按照步骤操作了吗?如果是的话,运行后你应该能够看到你放在“源文件夹”中的东西也被复制到了 bin 文件夹中。你是否使用了 Image image = ImageIO.read(getClass().getResource("/image/yourImage.extension")); 这段代码?其中的 image 是你在“源文件夹”中创建的文件夹名。 - nIcE cOw
我真的不知道,你是否按照我描述的所有步骤进行了操作,如果重新开始并遵循这些步骤,它应该可以工作,对于我来说,我已经制作了许多类似的jar文件,它们都可以正常运行。尝试访问此链接并获取此项目,这将告诉您项目结构。 - nIcE cOw
显示剩余2条评论

2

忘记类加载器,检查路径。如果可行,使用getResource而不是getResourceAsStream(风格问题:更直接,并在未找到时返回null)。

由于getResource(AsStream)是基于类的,因此路径是相对的,请尝试以下操作:

R.class.getResource("/" + resource)

1
创建一个资源包并将这个类和您的图像放入其中:
public final class Resources {

    public static ImageIcon getImage(String filename) {
        URL resourceUrl = Resources.class.getResource(filename);
        return new ImageIcon(resourceUrl);
    }
}

编辑:

我已经使用Maven和Flamingo(使用您的R类)重新构建了您的结构,并添加了以下内容,现在它可以正常工作:

更改:

R.class.getClassLoader().getResourceAsStream(resource);

至:

R.class.getResource("png/"+resource);

我已经使用了maven-assemble-plugin来构建jar,如此处所述。


在Eclipse中运行时图像可以正常显示,但在Eclipse之外运行时则无法显示。 - E-rich
请问你能否发布一些你的代码和项目结构? - Stefan
添加了我的项目结构。我不知道为这个问题能提供什么更多的代码;没有其他调用来检索图像资源。本地化 .properties 文件通过 ResourceBundle.getBundle("com.company.project.i18ln.MyGui") 访问,它正常工作。 - E-rich

0
URL imageurl = getClass().getResource("/images/serial-port-32x32.png");//relative path of the image as argument 
Image myPicture = Toolkit.getDefaultToolkit().getImage(imageurl);

使用图像“myPicture”作为ImageWrapperResizableIcon.getIcon方法的第一个参数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接