3

我正在尝试从 Jar 文件加载图像。这是行:

Image imgTrayIcon = new Image(display, this.getClass().getResourceAsStream("icon.ico"));

我见过很多使用这种方法的例子,但是当我尝试这样做时,我得到一个错误,说我的图像无效。这是堆栈跟踪:

 [java] Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid image
 [java]     at org.eclipse.swt.SWT.error(SWT.java:4083)
 [java]     at org.eclipse.swt.SWT.error(SWT.java:3998)
 [java]     at org.eclipse.swt.SWT.error(SWT.java:3969)
 [java]     at org.eclipse.swt.internal.image.WinICOFileFormat.loadInfoHeader(WinICOFileFormat.java:200)
 [java]     at org.eclipse.swt.internal.image.WinICOFileFormat.loadIcon(WinICOFileFormat.java:127)
 [java]     at org.eclipse.swt.internal.image.WinICOFileFormat.loadFromByteStream(WinICOFileFormat.java:119)
 [java]     at org.eclipse.swt.internal.image.FileFormat.loadFromStream(FileFormat.java:48)
 [java]     at org.eclipse.swt.internal.image.FileFormat.load(FileFormat.java:84)
 [java]     at org.eclipse.swt.graphics.ImageLoader.load(ImageLoader.java:130)
 [java]     at org.eclipse.swt.graphics.ImageDataLoader.load(ImageDataLoader.java:22)
 [java]     at org.eclipse.swt.graphics.ImageData.<init>(ImageData.java:331)
 [java]     at org.eclipse.swt.graphics.Image.<init>(Image.java:545)
 [java]     at SysTray.run(Unknown Source)

我使用的图标绝对有效。我已经使用图标工具检查了这一点。我还尝试将图标放在与我的代码相同的目录中(而不是 Jar-ing)并像这样使用它:

Image imgTrayIcon = new Image(display, "icon.ico");

这工作得很好,但是当我试图把它放在罐子里时,它没有。我似乎无法弄清楚为什么会这样。我已经解压缩了我的 Jar 以检查文件是否已添加到 Jar 中并且它似乎在那里。我的 jar 没有任何复杂的文件夹结构。所有文件和资源都在同一级别的树中。

关于这里有什么问题的任何想法?谢谢


这是一些复制问题的示例代码:

Example.java

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.graphics.*;

class Example {

    public static void main(String[] args) {
        Display display = Display.getDefault();
        Image imgTrayIcon = new Image(display, Example.class.getClassLoader().getResourceAsStream("icon.ico"));
    }

}

命令:

javac -cp "SWT.jar" Example.java
jar cf Example.jar *.class *.ico
java -cp "Example.jar;SWT.jar" Example
4

4 回答 4

3

好像您正在开发多线程应用程序。从堆栈跟踪Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid image看来,您正在将图像加载到非 ui 线程中并尝试在某些 UI 元素中使用它。看到这个

在 UI 线程中,以下代码可以正常工作。(图标文件在里面test package

package test;

import java.io.InputStream;

import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class IconTest 
{
    public static void main(String[] args)
    {
        final Display display = new Display();

        Shell shell = new Shell(display);
        shell.setLayout(new FillLayout());
        shell.setSize(200, 200);
        shell.setLocation(20, 20);

        InputStream stream = IconTest.class.getResourceAsStream("/test/icon.ico"); 

        Image imgTrayIcon = new Image(display, stream);

        shell.setImage(imgTrayIcon);

        shell.open();
        while (!shell.isDisposed()) {
                if (!display.readAndDispatch())
                        display.sleep();
        }

        if(imgTrayIcon != null)
            imgTrayIcon.dispose();

        display.dispose();
    }
}
于 2012-06-05T12:16:23.000 回答
0
ImageIcon image = (new ImageIcon(getClass().getResource("yourpackage/mypackage/image.gif")));

通常,您可以通过以下方式检索 InputStream:

InputStream is = this.getClass().getClassLoader()    .getResourceAsStream("yourpackage/mypackage/myfile.xml");

它将在罐子内部或外部运行。

参考http://www.jugpadova.it/articles/2006/02/05/accessing-a-resource-within-a-jar

另请参阅http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html

于 2012-06-05T11:29:51.037 回答
0

试试这些—— this.getClass().getClassLoader().getResourceAsStream("icon.ico")this.getClass().getClassLoader().getResourceAsStream("package_or_full_path_to_image/icon.ico" )Name_of_THIS_CLASS.class.getClassLoader().getResourceAsStream("icon.ico")

于 2012-06-05T12:10:34.703 回答
0
  1. 您是否尝试过将文件放在与类文件相同的目录中,而不使用 Jaring 并使用getResourceAsStream()来加载它?
  2. 您是否尝试过在 Jar 内部和外部使用java.security.DigestInputStream获取流的校验和,以查看两个环境之间的文件是否真的有任何不同?
于 2012-06-05T13:53:40.287 回答