Loading images...

I’m having problems when I pack my game into a jar, it won’t load images right… Read somewhere that I had to use class.getClassLoader().getResource() or something to get it right? Also, should I use BufferedImage?(is it faster?)

I’m using a singleton-class “BildeButikk” (ImageShop in english) to load images.

Image background = BildeButikk.get().getImage(“b.png”);

code:


package superspillet;
import java.util.HashMap;
import javax.swing.ImageIcon;
import java.net.URL;
import java.awt.*;

/**
 * BildeButikk.java
 * Singleton for å hente bilder.
 */
public class BildeButikk
{
    private static BildeButikk      butikk = new BildeButikk();
    private HashMap                 bilder;
    public BildeButikk()
    {
        bilder = new HashMap();
    }

    public static BildeButikk get()
    {
        return butikk;
    }

    public void removeImage(String id)
    {
        //dispose??
        bilder.put(id,null);
    }

    public Image getImage(String id)
    {
       if(bilder.get(id)==null)
       {
           try
           {
               //Config.get.getPath("bilder") returns "data/bilder/"
               Image tmp = loadImage(Config.get().getPath("bilder") + id);
               bilder.put(id, tmp);
           }
           catch(Exception e)
           {
               System.out.println("Kunne ikkje laste bilde: " + id);
               System.exit(0);
           }
       }
       return (Image) bilder.get(id);
    }

    /**********************************
    * metode for å laste bilde
    * @param fileName Filnavnet på bilder som skal lastes.
    *              f.eks.  "bilder/b.gif"
    * @return Image et objekt av klassen Image
    **********************************/
    private Image loadImage(String fileName)
    {
        //URL newFileName = this.getClass().getClassLoader().getResource(fileName);
        Image xx = null;
        try
        {
            xx = new ImageIcon(fileName).getImage();
        } 
        catch(Exception err)
        {
            System.out.println("Feil ved lasting av bilde.:" + err.getMessage());
            err.printStackTrace();
        }
        return xx;
    }
}

Hey, i have the same Problem (-:

I have opened the “Create a valid URL Object”-Thread

I havn’t found the solution yet, so i can’t really help you…

You have to use


import java.io.BufferedInputStream;
import java.io.InputStreamReader;


InputStreamReader fr = new InputStreamReader(new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(ref))); 
         
BufferedReader br = new BufferedReader(fr); 

then you will be able to read from a jar file,

btw “ref” is a string to you file location!

hmmm, norwegian code :wink:

The way to load images with ImageIO is as follows:


BufferedImage src = javax.imageio.ImageIO.read( 
                        new BufferedInputStream(getClass().getClassLoader().getResourceAsStream(resourcePath)));

If you make the getImage function static then getClass() will not compile. Then you have to call getClass() on an instance on one of your classes. Call getClass() on a java.awt.Point and you might get the wront class loader. This might be what is tripping you up, Nimloth. Can also try Thread.currentThread().getClass().

resourcePath is the relative path to the image. Always use “/” as seperator and always start with a “/”, even if it is in the root.

Make sure the image is in the correct place. Remember that path is case sensitive.

Disclaimer: I might be wrong about some of details.

Thx for the Hint Tom, i use the Classloader of my resource class


public static URL getFileURL(String aFile) {
  String file = "/"+ aFile;
    System.out.println(file);
    return Resource.class.getClassLoader().getResource(file);
//        return getURL("file:"+aFile);
      }

The uncomment Version was earlier - this worked. The classloader still does not… Here the List of the things that i tried:

  • The Jar File is on the same Directory Level as the Image (Resources) Directories are. I put that Directory in the classpath:

D:\projects\temp>java -classpath D:\projects\temp -jar sajotris.jar

  • i repleaced “/” with “”
  • i placed the resources in the same Directory where the classfiles are

Java always can’t find the resource
“/fonts/Blox2.ttf”

I tried everything - except the right (-:

Have you tried without using executable jars? The manifest has a Class-Path attribute that might mess with your classpath. Try this instead:
D:\projects\temp>java -classpath .;sajotris.jar YourMainClassHere

Can’t get it to work… I’ve tried anthing I can think of now…

:frowning:

    
private BufferedImage loadImage(String s)
    {
        BufferedImage src = null;
        try
        {
            BufferedInputStream inStream = new BufferedInputStream(getClass().getClassLoader().getResourceAsStream("/"+s));
            src = javax.imageio.ImageIO.read(inStream);
            //System.out.println("laster: "+s+" som er: "+src);
        }
        catch(Exception e)
        {
            System.out.println("feil ved lasting av bilde: "+s);
            e.printStackTrace();
            System.exit(0);
        }
        return src;
    }

The problem is that the src object is null… According to javadoc the read() method in ImageIO returns null if no registered ImageReader claims to be able to read the stream… My guess is that it can’t find the image?

Example of s: “data/bilder/ting/box1.gif”

I’m using JBuilder X,… The file structure in the jar-file:
[SuperSpillet.jar]
-data
—bilder
-----ting
-------box1.gif
-superspillet
—BildeButikk

@tom

I tried that. I tried your version, I extracted the jar and tried, but it doesn’t work.

I now know that my problem is classpath-related… If I move the data folder to the folder called classes(this is where JBuilder put my compiled files) then it works with
getClass().getClassLoader().getResource(…)… But the problem is that when I press “rebuild”, JBuilder deletes all files in the classes folder… :frowning: I lost A LOT of my new graphics this way >:(

So, I want to have the “data” folder in the project folder right next to “src” and “classes”… This works with jar if I add the following to the manifest:
Class-Path: .;superspillet;

But it doesn’t work inside JBuilder, but I guess it will when I figure out how to change the classpath… Anyone know how to do this? If I go to project -> project properties -> classpath
I see the classpath, but can’t change it…

finally it works ;D

Yes, it works finally. I found an article which says that the “Jar Classloader” won’t take any -classpath command line Arguments.

Here the Article:

http://www-106.ibm.com/developerworks/java/library/j-onejar/