-1

i have an application that loads an image to create a button with an icon in it. When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.

Location of images :

+Project
   -Source Packages
      -Tools
         -start.jpg

The code used :

     static final String STARTIMAGE = "/Tools/start.JPG";

public static JButton createStartButton() {

    Image img = Toolkit.getDefaultToolkit().getImage(GUITools.class.getResource(STARTIMAGE));

    JButton b = new JButton("",new ImageIcon(img));
    b.setPreferredSize(smallButton);
    b.setMaximumSize(smallButton);
    b.setMinimumSize(smallButton);

    return b;       

Now, the weirdest thing is that in another screen, a button is created in the exact same way, and this one works just fine... Code:

static final String PREVIOUSIMAGE = "/Tools/previous.gif";

public JButton createPreviousButton(){

    Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));
    JButton b = new JButton("Previous",new ImageIcon(img));
    b.setPreferredSize(dimensionButton);
    b.setMaximumSize(dimensionButton);
    b.setMinimumSize(dimensionButton);      

    return b;       
}

The only difference is that one is static, but even if make it non-static like the other one, it still won't work.

I tried everything I found on this forum and other sites, including this good topic :

How to bundle images in jar file (The generated url at the end of the topic is just 'null')

Nothing seems to work... Please help!

Thanks!

Community
  • 1
  • 1
Xaviraan
  • 73
  • 1
  • 5

2 Answers2

0

When started from the IDE, it works just fine, but when started from an exported jar file, it gives an image fetching error.

Image img = Toolkit.getDefaultToolkit().getImage(getClass().getResource(PREVIOUSIMAGE));

This approach above is incorrect, use this instead:

private static BufferedImage readBufferedImage (String imagePath) {
    try {
        InputStream is = YourClassName.class.getClassLoader().getResourceAsStream(imagePath);
        BufferedImage bimage = ImageIO.read(is);
        is.close();
        return bimage;
    } catch (Exception e) {
        return null;
    }
}

And better load all images at application startup and then use them.

Nikolay Kuznetsov
  • 9,467
  • 12
  • 55
  • 101
  • 1
    No. As the question shows, the approach is correct, much simpler than your code, and less error-prone. And it doesn't ignore exceptions like your code does. – JB Nizet Jan 24 '13 at 14:19
  • 1
    @JBNizet, are you sure that reading image from `JAR` with `Toolkit.getDefaultToolkit().getImage()` is okay? And why you think my code is error-prone? – Nikolay Kuznetsov Jan 24 '13 at 15:30
  • @JBNizet, I always considered that `ImageIO.read` should be used for jar files. – Nikolay Kuznetsov Jan 24 '13 at 15:31
  • 1
    Why wouldn't it? You pass an URL to the method, and it loads the image at that URL. That's what it does. Your method is error-prone because it doesn't document what imagePath is, because it throws checked exceptions that almost all newbies handle incorrectly, like you're doing. – JB Nizet Jan 24 '13 at 15:54
0

It seems to me that your images are inside a package so the actual link might be "package.name/Tools/start.jpg" or something else when its compiled so the image should be moved.

Instead of having it inside of a package like:

+Project
   -Source Packages
     -Tools
       -start.jpg

Do something like this instead.

+Project Folder
  -Source Packages/
  -Tools/
    -start.jpg
1amnick
  • 43
  • 3
  • The image is in the package Tools, and the path is /Tools/start.jpg, so the OP is doing the right thing. Putting it outside of the sources will prevent the image to be "compiled" to the classes directory and included in the jar, thus making it unavailable from the class loader. – JB Nizet Jan 24 '13 at 15:02