Reputation: 45108
I'm trying to load an image from a Jar File. Here's the line:
Image imgTrayIcon = new Image(display, this.getClass().getResourceAsStream("icon.ico"));
I've seen many examples using this method but when I try to do so, I get and error saying that my image is invalid. Here's the stack trace:
[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)
The icon I'm using is definitely valid. I've checked this using icon tools. I've also tried placing the icon in the same directory as my code (not Jar-ing it) and using it like this:
Image imgTrayIcon = new Image(display, "icon.ico");
This works just fine, but when I try to put it in the Jar, it doesn't. I can't seem to figure out why this is happening. I've uncompressed my Jar to check whether the file was added to the Jar and it seems to be there. My jar doesn't has any complex folder structure. All the files and resources are in the same level of tree.
Any ideas on what's wrong here? Thanks
Here's some sample code to replicate the issue:
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"));
}
}
Commands:
javac -cp "SWT.jar" Example.java
jar cf Example.jar *.class *.ico
java -cp "Example.jar;SWT.jar" Example
Upvotes: 3
Views: 5771
Reputation: 2376
getResourceAsStream()
to load it?Upvotes: 0
Reputation: 13984
Seems like you are working on multi-threaded application.
From the stack-trace Exception in thread "Thread-0" org.eclipse.swt.SWTException: Invalid image
it appears that you are loading the image in a non-ui thread and trying to use that in some UI element. See this.
Within a UI thread the below code works fine. (The icon file is inside the 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();
}
}
Upvotes: 3
Reputation: 3116
Try these -
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")
Upvotes: 0
Reputation: 30688
ImageIcon image = (new ImageIcon(getClass().getResource("yourpackage/mypackage/image.gif")));
In general, you can retrieve an InputStream in the following way:
InputStream is = this.getClass().getClassLoader() .getResourceAsStream("yourpackage/mypackage/myfile.xml");
It will run inside or outside the jar.
refer http://www.jugpadova.it/articles/2006/02/05/accessing-a-resource-within-a-jar
also refer http://docs.oracle.com/javase/tutorial/uiswing/components/icon.html
Upvotes: 0