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.

我难住了。我花了几个小时试图弄清楚这一点,但可以使用一些帮助。有任何想法吗?

仅供参考:我认为这并不重要,但我使用Flamingo作为我的 GUI。

编辑:根据 Stefan 的要求

源/
    主要的/
        爪哇/
            com.company.project(包)
                R.java
                MyGui.java
        资源/
            com.company.project(包)
                .png(包)
                    串行端口 32x32.png
                    (更多图片)
                .i18ln(包)
                    MyGui.properties

至于更多代码,我不知道我还能提供什么对这个问题有很大好处。上面提供了用于检索资源的所有代码以及我如何使用该代码。您是否正在寻找特定的东西?

更新:

当我使用 Eclipse 创建一个 Jar 并从命令行运行它时,图像资源会正确显示。当我使用 Gradle 创建 Jar 时,不显示图像。因此,在生成允许通过 Eclipse Jar 而不是 Gradle Jar 正确访问图像资源的 Jar 时,有一些不同的做法。关于这个问题,我在 Gradle 论坛上提出了一个问题

4

5 回答 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");
于 2012-05-11T14:34:26.577 回答
2

在这里尝试这个示例如何将图像加载到您的 ECLIPSE 项目中。希望这将为您解释,更多步骤在这里

不要使用 ClassLoader,尽管如此Java Doc中所述,引用它的一段话指出“所有类加载器都会首先搜索资源作为系统资源,其方式类似于搜索类文件。”

于 2012-05-11T14:28:30.730 回答
2

忘记类加载器,检查路径。如果可行,请使用 getResource io getResourceAsStream (风格问题:更直接,找不到时提供 null )。

由于 getResource(AsStream) 是基于类的,路径是相对的,所以试试这个:

R.class.getResource("/" + resource)
于 2012-05-11T15:47:26.607 回答
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,如此所述。

于 2012-05-11T13:11:52.150 回答
0
URL imageurl = getClass().getResource("/images/serial-port-32x32.png");//relative path of the image as argument 
Image myPicture = Toolkit.getDefaultToolkit().getImage(imageurl);

使用此 Image 'myPicture' 作为 ImageWrapperResizableIcon.getIcon 方法的第一个参数

于 2012-08-21T10:55:16.050 回答