views:

699

answers:

4

When a .jar of an application is created, the images in the application no longer appear. An example of our code for loading images is: ImageIcon placeHolder = new ImageIcon(src\Cards\hidden.png);

We have no idea why this is happening. The application runs as expected if we do not compress it to a .jar; as a .jar, the images simply disappear. We also tried using URLs instead of ImageIcons, but that just causes the program not to run at all.

Any ideas?

EDIT: We are putting the image files into our .jar file in the correct paths, so that's not the problem.

+2  A: 

You should load resources from the classpath as such:

 InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Cards/hidden.png")

This of course assumes that when you create the JAR, you are actually putting the image files into it.

There is also a method for getting the resource as a URL.

matt b
From the javadoc you linked to: "The name of a resource is a '/'-separated path name that identifies the resource." You may want to correct the path in your example, which uses a backslash :-)
Grundlefleck
+1  A: 

Question: Does the folder src exist in the jar?

Tip: You can open .jar with any unpacking program which supports ZIP to see its contents.

Answer: The way you reference the resource is incorrect, you should do something like getClass().getClassLoader().getResource("Cards/hidden.png") instead.

Esko
Why is it "incorrect"?
Mana
Because you amenend it as a relative disk file system path instead of as a classpath resource.
BalusC
+3  A: 

I asked the same question a while back. You should find your answers here.

jjnguy
+4  A: 

Check the API for the constructor you're calling. The string you pass in is a file path - when the resources are packaged in a JAR, there is no file on the filesystem containing the image, so you can't use this constructor any more.

Instead you'd need to load the resources from a stream, using the classloader, and pull them into a byte array:

byte[] buffer = new byte[IMAGE_MAX_SIZE];
InputStream imageStream = getClassLoader().getResourceAsStream("src\Cards\hidden.png");
imageStream.read(buffer, 0, IMAGE_MAX_SIZE);
ImageIcon placeHolder = new ImageIcon(buffer);

Needs more exception and edge-case handling, of course, but that's the gist of it.

Andrzej Doyle
`MyClass.class.getClassLoader()`. Forward slashes would at the very least be preferred. And `read` does not always read the full buffer (`DataInputStream.readFully`, for example, does that).
Tom Hawtin - tackline
There is a simpler way to load the image by using getClass().getResource("image.png"). This returns correct URL either for file system or jar. This URL can be used then in many ways icluding new ImageIcon(url)
eugener