Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm using Slick2d for a game, and while it runs fine in Eclipse, i'm trying to figure out how to make it work when exported to a runnable .jar. I have it set up to where I load every image located in the res/ directory. Here's the code

/**
 * Loads all .png images located in source folders.
 * @throws SlickException
 */
public static void init() throws SlickException {

    loadedImages = new HashMap<>();
    try
    {
        URI uri = new URI(ResourceLoader.getResource("res").toString());
        File[] files = new File(uri).listFiles(new FilenameFilter(){
            @Override
            public boolean accept(File dir, String name)
            {
                if(name.endsWith(".png"))
                    return true;
                return false;
            }

        });

        System.out.println("Naming filenames now.");

        for(File f:files)
        {
            System.out.println(f.getName());
            FileInputStream fis = new FileInputStream(f);
            Image image = new Image(fis, f.getName(), false);
            loadedImages.put(f.getName(), image);
        }
    } catch (URISyntaxException | FileNotFoundException e)
    {
        System.err.println("UNABLE TO LOAD IMAGES FROM RES FOLDER!");
        e.printStackTrace();
    }

    font = new AngelCodeFont("res/bitmapfont.fnt",Art.get("bitmapfont.png"));

}

Now the obvious problem is the line URI uri = new URI(ResourceLoader.getResource("res").toString()); If I pack the res folder into the .jar there will not be a res folder on the filesystem. How can I iterate through all the images in the compiled .jar itself, or what is a better system to automatically load all images?

share|improve this question
    
this sounds more like a java question, I would suggest try it under SO site. –  zinking Jun 11 '12 at 7:11
add comment

2 Answers 2

up vote 1 down vote accepted

I had this same problem a week ago, and the solution is to use InputStreams. I don't know how ResourceLoader from Slick works, but files are correctly loaded both in filesystem and in JARs using this code:

String filepath = "/package1/package2/file.lol";

InputStream inputStream = ClassLoader.class.getResourceAsStream(filepath);

and in your code you can do for example:

FileInputStream fis = (FileInputStream) inputStream;

If - like in your code - you want to search for files in directories, you have to write different code for the two cases(filesystem and jar):

URL url = this.getClass().getResource(directoryPath);
File directory = new File(url.getFile());

if (directory.exists()) {
     // we are running this code from filesystem
} else {
     // we are running this code from jar
}

You can find my implementation here (line 130).

share|improve this answer
    
Haha, looking at your implementation helped a bunch! Thank you very much! –  Rahat Ahmed Jun 11 '12 at 15:59
    
Glad that it helped you :) –  integeruser Jun 11 '12 at 16:38
add comment

This one just does not work this way.

You can't list files by directory inside a JAR file. Those files are placed inside the classpath when running the JAR and you need to access every file directly by its name. Access based on the folder structure does not work when accessing files inside the classpath.

You don't "notice" the difference in loading in this case because you are using the ResourceLoader that comes with Slick. In general that is the correct thing to do, but in this case it "hides" the fact that the classpath data is load and not the filesystem data.

So you either need to write down explicit what files you want to load or you need to generate some sort of file list while building the JAR file. Or you need a naming conversation that allows you to load all images. Something like image0000.png, image0001.png, image0002.png, ...

In case you choose to use a filelist you may look at the ANT build system and at fileset, filelist and pathconverter in order to get the automated generation of those lists going.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.