2012-06-05 4 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) 

Значок, который я использую, определенно действителен. Я проверил это с помощью инструментов значков. Я также попытался поместить значок в том же каталоге, что и мой код (не Jar-ки его) и использовать его как это:

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

Похоже, вы работаете на многопоточном приложении. Из строки stack-trace Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid image похоже, что вы загружаете изображение в не-ui-потоке и пытаетесь использовать его в каком-то элементе пользовательского интерфейса. See this.

Внутри пользовательского интерфейса нижеследующий код работает нормально. (Файл значок находится внутри 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 = новое изображение (display," icon.ico ");' тогда SWT вызывает собственный метод ... который, в свою очередь, вызывает собственный API-интерфейс win32 GDI +. Возможно, вы захотите найти 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

Да, я понял это немного, но у меня нет какой-либо структуры пакета внутри моего Jar. Все файлы находятся на одном уровне, поэтому я ссылаюсь на это следующим образом: 'this.getClass(). GetClassLoader(). GetResourceAsStream (" icon.ico ");'. Я проверил, что файл существует в Jar, запустив 'jar tf '. Я все равно получаю ту же ошибку. –

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")

0
  1. Вы пробовали положить файл в том же каталоге, что и файл класса, без Jaring, и используя getResourceAsStream(), чтобы загрузить его?
  2. Вы пытались получить контрольную сумму потока, используя java.security.DigestInputStream, в то время как внутри и за пределами Jar, чтобы увидеть, действительно ли файл отличается друг от друга между двумя средами?
Смежные вопросы