How to get the right Path?

I’ve been attempting to get a map loader working for the past hour or so now and it looks as if it should work but I can’t seem to figure out how to get the proper path to load my TestMap.png resource. I checked around a bit and it seems as if I should be using an InputStream but the InputStream doesn’t have .getWidth() or .getHeight() so I couldn’t use it; after that I tried a few different paths but none of them seemed to work.

The resource I’m attempting to load is in C:\Users\MyName\Java Projects\Sword\src\Resources\Maps and the class trying to load it is within C:\Users\MyName\Java Projects\Sword\src\Functions\ I want this to be able to work after I’ve compiled everything into a .jar file later on as well so I’m not sure how to get this working now and for later when the path changed when it’s within the .jar file. If anyone knows how to do this, please do tell.

Image loading code:

package Functions;

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

public class MapLoader 
{
    public MapLoader()
    {
    }
    
    public int[][] loadMap(String x) //Requires the map's file name. Don't include the extension.
    {
        int[][] map;

        BufferedImage bufferedImage = null;
        try
        {
            String y = "/Resources/Maps/" +x+ ".png";
            bufferedImage = ImageIO.read(new File(y));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        int[] pixels = new int[width * height];
        bufferedImage.getRGB(0, 0, width, height, pixels, 0, width);
        
        map = new int[width][height];
        //this channels the 1 dimensional pixel[] into the two dimensional map[][]
        for(int row = 0; row < height; row++)
        {
            for(int column = 0; column < width; column++)
            {
                map[column][row] = pixels[row * width + column];
            }
        }
        
        return map;
    }
}

I’m basing this all off of nhmllr’s code from this thread: http://www.java-gaming.org/index.php/topic,28841.0.html#msg263301

use the ClassLoader to find the resource you’re looking for as an URL.

URL url = this.getClass().getClassLoader().getResource(String name);
BufferedImage bimg = ImageIO.read( url );

An URL is a fancy class that tries to represents your resource for you in various ways (OS independandtly) and the ClassLoader is a fancy thing that tries to locate that resource based on its name also in nifty ways (relatively, OS independantly). IIRC.

So since the calling class is in ‘/Functions’ and the resource is in ‘/Resources’ and they’re both in ‘/src’ which is in the class path I think the ClassLoader should be able to find it by simply its name so [x + “.png”] in this case or if not then specify it as ["/Resources/" + x + “.png”].

I just re-wrote a few parts to see if I could get it working with a URL; for some reason url is always null even though I specify the path to it. Have I written this incorrectly?

URL statement:

URL url = this.getClass().getClassLoader().getResource("/Resources/Maps/"+x+".png");

Full Code:

package Functions;

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

public class MapLoader 
{
    public MapLoader()
    {
    }
    
    public int[][] loadMap(String x) //Requires the map's file name. Don't include the extension.
    {
        int[][] map;
        
        
        URL url = this.getClass().getClassLoader().getResource("/Resources/Maps/"+x+".png");
        System.out.println(url);
        BufferedImage bufferedImage = null;
        try
        {
            bufferedImage = ImageIO.read(url);
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }

        int width = bufferedImage.getWidth();
        int height = bufferedImage.getHeight();
        int[] pixels = new int[width * height];
        bufferedImage.getRGB(0, 0, width, height, pixels, 0, width);
        
        map = new int[width][height];
        //this channels the 1 dimensional pixel[] into the two dimensional map[][]
        for(int row = 0; row < height; row++)
        {
            for(int column = 0; column < width; column++)
            {
                map[column][row] = pixels[row * width + column];
            }
        }
        
        return map;
    }
}

Try taking the first “/” out of the path in getResource("/Resources/Maps/"+x+".png");

-> getResource(“Resources/Maps/”+x+".png");

That seems to have done it; thanks for all the help!

The “trick” here was that beginning the file name with a forward slash “/” will make the ClassLoader look for the resource as if it’s an absolute path, essentially skipping the magic we’re looking for.

http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResource(java.lang.String)

http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#findResource(java.lang.String)

http://mindprod.com/jgloss/getresourceasstream.html