I have no idea how to get my images to work in a Jar!

(I’ve attempted to put the tl;dr stuff in bold)
Hey everyone, I’m totally new here and relatively new to Java, I was hoping I could get some help regarding a practice game I’m making.
I did a few searches, I didn’t find anything like this, but I also wasn’t going to spend my entire evening tunneling through forum searches XD

Anyway, my game was working fine when I ran it in Eclipse, but I wanted to be able to show it to my buddies, I exported it as an executable Jar and ran it.
Nothing ran at all. So I looked into it and apparently my images aren’t loading up properly when I run the Jar.

Why is it that Eclipse can find my images and run the thing fine and when I export it nothing works?
I’m assuming it’s to do with where I placed my files. I HAVE NO IDEA WHERE TO PUT THEM! But I do want them in an images folder at the very least.
I’ve currently got them in “src/platformer/images”
Platformer is my package name/folder and has all my code in there.

The code I’m using to load the images up has changed a few times, but what I’m currently using is:

BufferedImage blockTileset = ImageIO.read(this.getClass().getResource(“images/tiles.png”));

Now I’m not entirely sure what I’m doing there, I just read from Kev Glass’ tutorials that it’s a good idea to do it that way.
Can anyone lend some insight into this? Do I need to move my images folder somewhere? Do I need to add a slash or something to my file path? I’ve spent all day on this annoying problem and haven’t got anywhere! I know it’s a simple, stupid problem, but please bear with me!

Thanks in advance :slight_smile:

P.S. You may need to dumb down your answers a little bit, I’m not a full on programmer yet! So many things I’ve looked up today where people had problems that were solved thusly, ‘Simply do this! insert a whole mess of uncommented code with poorly named variables’ ‘Wow thanks for solving my problem! :D’. Then you have me sitting here, thinking in angry scribbles and reaching for another coffee…

can you write the filestructure of your jar?
what folders are in there, and where did you put the ressources

Sure thingy! It’s a really small, simple project.

I opened the Jar in 7zip and got the following:

platformer > images > All my images
| All my code

META-INF > manifest.mf

I hope that’s readable enough! :slight_smile:

try

BufferedImage img= ImageIO.read(new File("…/images/clown.png"));

or

BufferedImage img= ImageIO.read(new File("…/platformer/images/clown.png"));

the …/ means you go up 1 folder

I’ve tried that before :frowning: I’m afraid it doesn’t work. Eclipse doesn’t even find the images when I do it like that. The Jar still falls over too.

BufferedImage img= ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream(“images/clown.png”));

where images/clown.png is in your jar, just like that.

Cas :slight_smile:

Sorry! That didn’t work either, I tried that code with “images/”, “/images/” and “…/images/”, still no good.
I’ll go ahead and paste in the class I’m using to hold my sprites, minus the getters.

public class Sprites 
{
   public BufferedImage[] sprites = new BufferedImage[4];
   private int tileSize = 32;
   
   public Sprites()
   {
      try
      {
         //Block tileset
         BufferedImage blockTileset = 
               ImageIO.read(this.getClass().getResource("images/tiles.png"));
         
         sprites[0] = 
               ImageIO.read(this.getClass().getResource("images/dude.png"));
         sprites[1] = 
               ImageIO.read(this.getClass().getResource("images/enemy.png"));
         
         //Loop through block tileset
         for (int i1 = 0; i1 < 1; i1++)
         {
            for (int i2 = 0; i2 < 2; i2++)
            {
               sprites[i2 + 2] = blockTileset.getSubimage(i2 * tileSize, 
                     i1 * tileSize, tileSize, tileSize);
            }
         }
      }
      catch (Exception e)
      {
         System.out.println(e.getMessage());
      }
   }

If you’re wondering about the nested for loops, I’m leaving those in for when my sprite sheet exceeds two sprites haha!

I still think it’s probably to do with where I’ve put the images. The images folder is in the same directory as all my code, surely that would be ok?

In Eclipse you must assign your resourcefolder as class-folder under properties

That’s starting to sound like the solution to my problem!
See I only just switched over to Eclipse yesterday, I’ve been trying to learn it as best I can, yet a little thing like this seems to have slipped under my radar.
So the properties where I assign this as a resource folder, is that the properties from the project menu? Or is it the properties from right clicking on the folder itself? Also, whereabouts in properties? Is it build path or linked resources or something I’ve missed entirely?

Sorry to waste time on such a small little problem!!

rightclick on the project in the list, select propertes->java_buildpath
and add the imagefolder as resourcefolder

Well I opened the project properties, went to build path, went to the source tab, added the folder and this is what happened…
Some deal about enabling nesting? Does this mean my folders are whack?

http://dl.dropbox.com/u/1289341/curses.jpg

I think Cas is right here, but in your current zip layout, your images were in “platformer/images”. So I believe it would be:


BufferedImage img= ImageIO.read(Thread.currentThread().getContextClassLoader().getResourceAsStream("platformer/images/clown.png"));

I used that code you suggested, it worked in Eclipse, but after exporting is an executable Jar, still didn’t work.
I seriously think something is wrong with my folders or something. Am I correct in assuming that the images folder should be a source folder in the Java Build Path in properties? Because I’ve tried that too, and it broke it again :frowning:
I’m definately doing SOMETHING wrong though, since I’ve looked through tons of videos today and they just breezed through it…

EDIT: Here’s a picture of my little project list that might shed some light on the subject. I’m not sure that images folder is in the right place, I’ve moved it around a fair bit though…

http://dl.dropbox.com/u/1289341/foldedup.jpg

When using Class.getResource, you must know that it is relative to the Class. The easiest way to get a resource is to put a forward slash at the beginning of the path. This signifies the root of the jar file when in a JAR file or the root of your project (the src folder). In this situation, remove the “platformer.images” from the build path. To load any file, use ImageIO.read(Class.getResourceAsStream("/platformer/images/MyFile.png"));

EDIT: There is no difference between using Class and the Thread.currentThread().getContextClassLoader() way.

EDIT2: In your project image, that white colored “package icon” means there are no files under that folder…

Use getClass().getResourceAsStream(). This gives you a reference relative to the current class, using its classloader, which is much more likely to do what you want. This doesn’t matter much for the average toy app, but if you ever write web apps or god forbid mess with OSGi, you’ll absolutely hose yourself if you start grabbing random classloaders or try to use the boot one.

It means there aren’t any source files in the folder. There could be images, .properties files, etc.

ra4king looks at Eclipse again oh…whooops…you’re right ;D

It’s a rite of passage to work on an “enterprise” application and bang your head against the wall tinkering with classloaders.

At this point, I’m not even sure what exactly a class loader is, I just read that if I do it this kind of way it’s better :persecutioncomplex:.
I certainly appreciate all the time you guys are putting into helping me out, I’ve done what I think you guys were telling me to do, it looks like this now:

http://dl.dropbox.com/u/1289341/Bugs/Consarnit.jpg

However, it’s not even running in Eclipse anymore… :frowning:
So let me get this straight, the src folder is treated as the root directory right? So surely putting the images folder in src folder would mean that the path, “/images/myfile.png” would work right? …Cause it’s not. I really think the problem is WHERE I’m putting my images folder, I simply just don’t know the correct place for it.
This is such a rediculous error for me to be stuck on…

Don’t add it to the build path though!

The best way is to make a “res” folder inside src: