2012-06-05 77 views
3

我试图从Jar文件加载图像。这里的行:无法从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) 

我使用的图标是绝对有效的。我使用图标工具检查了这一点。我也试着放置在同一个目录的图标为我的代码(不是瓶子-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 

回答

3

好像你是在多线程应用程序的工作。 从堆栈跟踪Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid image看来,你正在加载图像在非UI线程中,并试图在一些UI元素中使用它。 See this

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

Hi Favonius。我想我找到了原因。它似乎与线程无关,等等。我的图标是一个多分辨率图标。我可以使用这个图标就好,如果我加载它直接加载它,但似乎从资源加载多分辨率图标会导致问题。你知道这件事吗?我用一个简单的图标文件来测试我的例子,该文件只有一个分辨率,并且工作得很好。这是我尝试使用的图标:http://findicons.com/icon/64852/download_box?id=345962。 –

+1

看起来像SWT实施中的错误。即使InputStream stream = new FileInputStream(“icon.ico”);代码也会失败。附:问题出在多分辨率图标上。 **但是,当你执行'imgTrayIcon = new Image(display,“icon.ico”);'然后SWT调用一个本地方法......这又调用一个本地的win32 GDI + API。你可能希望寻找一个SWT错误...如果找不到,然后提出一个! – Favonius

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

+0

它似乎没有工作。如果我尝试加载一个'ImageIcon',它可以工作,即我没有看到任何错误。我有一个SWT应用程序,并没有使用Swing小部件。 –

+0

只是一个重要的例子是指定getClass()。getResource(“yourpackage/mypackage/image.gif”)的方式 –

+0

是的,我明白了这一点,但是我的罐子里没有任何包装结构。所有的文件都在同一层次上,因此我们可以这样引用它:'this.getClass()。getClassLoader()。getResourceAsStream(“icon.ico”);'。我通过运行'jar tf '来检查文件是否存在于Jar中。我仍然得到相同的错误。 –

0

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

0
  1. 你试图把文件在同一目录下的类文件,没有JARING它,并使用getResourceAsStream()加载它?
  2. 您是否试过在Jar内部和外部使用java.security.DigestInputStream来获取流的校验和,以查看文件在两种环境之间是否实际上存在任何差异?