Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access resources in JAR file?

I have a Java project with a toolbar, and the toolbar has icons on it. These icons are stored in a folder called resources/, so for example the path might be "resources/icon1.png". This folder is located in my src directory, so when it is compiled the folder is copied into bin/

I'm using the following code to access the resources.

    protected AbstractButton makeToolbarButton(String imageName, String actionCommand, String toolTipText,
        String altText, boolean toggleButton) {

    String imgLocation = imageName;
    InputStream imageStream = getClass().getResourceAsStream(imgLocation);

    AbstractButton button;
    if (toggleButton)
        button = new JToggleButton();
    else
        button = new JButton();

    button.setActionCommand(actionCommand);
    button.setToolTipText(toolTipText);
    button.addActionListener(listenerClass);

    if (imageStream != null) { // image found
        try {
            byte abyte0[] = new byte[imageStream.available()];
            imageStream.read(abyte0);

            (button).setIcon(new ImageIcon(Toolkit.getDefaultToolkit().createImage(abyte0)));

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                imageStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } else { // no image found
        (button).setText(altText);
        System.err.println("Resource not found: " + imgLocation);
    }

    return button;
}

(imageName will be "resources/icon1.png" etc). This works fine when run in Eclipse. However, when I export a runnable JAR from Eclipse, the icons are not found.

I opened the JAR file and the resources folder is there. I've tried everything, moving the folder, altering the JAR file etc, but I cannot get the icons to show up.

Does anyone know what I'm doing wrong?

(As a side question, is there any file monitor that can work with JAR files? When path problems arise I usually just open FileMon to see what's going on, but it just shows up as accessing the JAR file in this case)

Thank you.

like image 210
bcoughlan Avatar asked Mar 06 '10 16:03

bcoughlan


1 Answers

I see two problems with your code:

getClass().getResourceAsStream(imgLocation);

This assumes that the image file is in the same folder as the .class file of the class this code is from, not in a separate resources folder. Try this instead:

getClass().getClassLoader().getResourceAsStream("resources/"+imgLocation);

Another problem:

byte abyte0[] = new byte[imageStream.available()];

The method InputStream.available() does not return the total number of bytes in the stream! It returns the number of bytes available without blocking, which is often much less.

You have to write a loop to copy the bytes to a temporary ByteArrayOutputStream until the end of the stream is reached. Alternatively, use getResource() and the createImage() method that takes an URL parameter.

like image 195
Michael Borgwardt Avatar answered Nov 15 '22 15:11

Michael Borgwardt