Exporting Jar in eclipse with images

Hello! i’m still learning the ways of Java and eclipse, i’ve started creating a space invaders clone(gotta start somewhere right?) But the game isn’t really where my problem is. I’ve spent the last few days trying to export to a jar file. And i finally managed it but then i hit a wall with my code within the jar trying to find the pictures.

Which is really where i’m still kind of confused. I found a site http://ubuntuforums.org/showthread.php?t=711238 that helped me out and now the code works but i don’t know why it works and that’s bothering me more then anything.

i’ve imported the images into eclipse to help automate the export into a jar file. I was able to manually copy the pictures into the jar and it worked before but i’d rather eclipse just handled it for me.

Anyway in the jar the files are under a folder called /Images/ and here’s the code i was using:


   private Image image;

   private String craft = "./Images/cannon.png";

   ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
   image = ii.getImage();

courtesy of: http://zetcode.com/tutorials/javagamestutorial/

Now i’m using


   java.net.URL imgURL = getClass().getResource("/Images/cannon.png");
   image = Toolkit.getDefaultToolkit().getImage(imgURL);

Now the code automagically works but i’m not sure why. I was wondering if someone could explain the differences between these two? Do i have to use the second one? is it more efficient? the path to the images looks like it was exactly the same so i’m not sure why the other one didn’t work. I noticed i needed to import java.awt.Toolkit for this one for obvious reasons. But i’m not sure what’s up with java.net.URL

Anyway i’d apreciate a point in the right direction. There’s so much code out there and so many ways to do things that i’m not all that sure whether i’m heading in the right direction or not. This could be a horribly inefficient way of doing it for all i know.

Hi!

The difference is the absence of the dot at the beginning of the path in the working example. The image is fetched from the JAR or a directory. If you put the dot, it looks in the “current” directory on the file system anyway whereas in the second case, in Java Web Start, it will look at the image in the JARs.

The dot signifies a relative URL so it will look for an folder called Images at the same level as whatever class you called “getClass()” from.
Using a forward slash signifies the root directory so it will look for an Image folder at the current working directory which is either the folder above the first package folder or the root inside of a jar file.

With the constructor new ImageIcon(string), the string is taken to be a file name. This is problematic when reading data from within a jar, as a file embedded within a jar does not have a “normal” file location for most operating systems.

I believe you could continue to use the ImageIcon constructor if the parameter you passed was a URL instead of a file name string. URL’s are able to “look inside” of a jar. Don’t ask me how! There’s more about URL’s, including the ability to use relative addressing here: http://download.oracle.com/javase/1.5.0/docs/api/java/net/URL.html

So, I’m guessing the following code should also work for you (relieving you of the task of importing/loading the Toolkit):


    URL imgURL = getClass().getResource("/Images/cannon.png");
    ImageIcon ii = new ImageIcon(imgURL);
    image = ii.getImage();

This is similar with what I ended up using in my game after a brief flirtation with the defaultToolkit method. I can’t say that I know much about the Toolkit. It seems like a pretty cool thing, but I haven’t used it.

  1. Using ImageIcon and getting the image there is ugly and not efficient. The way the OP should be getting images is via javax.imageio.ImageIO.

URL imgURL = getClass().getResource("/path/to/image.png");
BufferedImage image = ImageIO.read(imgURL);

  1. A URL points to a file inside a jar by using the special “!” character. For example lets say we have the jar file MyJar.jar and inside the jar we need “/myfolder/MyImage.png”, the URL would look like this:

file:/C:/Path/To/Jar/File/MyJar.jar!/myfolder/MyImage.png

  1. There is not point in using Toolkit for anything graphics-wise. Creating images and retrieving resources are done using specific tools made for the job.

I use code like this to load images.


import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

String fileName = "Images/cannon.png";
BufferedImage image = ImageIO.read( Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName) );

Just spotted this great article: “Loading images using getResource” embedded in “How to Use Icons”.
http://download.oracle.com/javase/tutorial/uiswing/components/icon.html

There doesn’t seem to be anything about needing to put in a “!” when a URL references a resource in a jar. I guess this is handled automatically when using the code snip below. The “seven configurations” referred to include the case where images are included within the same jar.

[quote]All seven configurations shown are valid, and the same code reads the image:

java.net.URL imageURL = myDemo.class.getResource("images/myImage.gif");
...
if (imageURL != null) {
    ImageIcon icon = new ImageIcon(imageURL);
}

[/quote]
I agree and like and used the same construct as the one you gave, ra4king, (e.g., “myBufImg = ImageIO.read(url);”). But I’m not dealing with IconImage objects in my program. Seems like one should prefer to load directly into the form one wants to use in the program, in general. In my case I was actually needing to get at the bits.

philfrei, have you tried printing out what you get from getResource? It automatically puts the “!” for you if it finds the file inside a jar file.

@ra4king Yes, I’ve seen it. I can’t recall if it was when I did a getFile() method on a URL or maybe its toString(). But, happily, it is not needed in the coding, when using getResource() as presented in the “Using Icons” tutorial I just cited. As I said, the use of the “!” must be handled behind the scenes, automatically, somehow or another.

Nothing about it in the java spec for URL either. Maybe it is covered somewhere else, perhaps in some documentation specifically about jars. I don’t understand why the URL section doesn’t say anything. It spends some time on things like the syntax needed for accessing ports, and about various parts of a URL. Mystery to me. Could be something client/OS specific. I don’t know. ???

appreciate the feedback guys!

i thought the ‘.’ was for referring to the directory i was in, not the directory prior to the one i was in. *shrug

So if i understand this right, the URL is important for referring to the images within the jar file?

“.” means the current directory. “…” means the directory above the current one.
And a URL is the only way to point to a location inside a Jar file.

I ended up switching the images back to the imageicon deally. I don’t know if that’s really the best way to do it but the collision detection wasn’t working with the url… and i am still learning so i didn’t want to make this more complicated then it had to be in the beginning.

Oh i think i just get what was up with the dot. it wasn’t looking inside the jar it was looking in the operating system right? Ok i get that.

oh and if anyone’s interested here’s the beginning of my space invader wannabe game http://davediel.com/chris/projects/Java/Cattack.jar It’s not impressive or even at demo status yet but you can shoot things and they will disappear :slight_smile: so i’m happy about it.

The code I posted above will load images from any jars in the classpath/archive tag. It also doesn’t create ToolkitImages or trip the SecurityManager.