2

I'm having massive issues packaging my java program which contains images into a jar for conversion into and executable file. The images have been used in the background of the program and buttons. Please see the diagram below which shows the program I desire to convert to a jar.

IMAGE

enter image description here

As you see above the program runs OK. I created the same program with no custom background and custom buttons containing no images and I successfully packaged it into a jar and subsequently into an .exe file.

With regards to drawing my background I'm doing this as follows:

public void paintComponent(Graphics g) {
    Image img = new ImageIcon("imgs/Bgnd1.jpg").getImage();
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
    setPreferredSize(size);
    setMinimumSize(size);
    setMaximumSize(size);
    setSize(size);
    setLayout(null);
    g.drawImage(img, 0, 0, null);
} 

With regards to creating my 4 custom buttons with images, I'm doing the following:

// Prepare rollover images
ImageIcon F1 = new ImageIcon("imgs/btn_f1_not_selected.jpg");
ImageIcon F1rollOver = new ImageIcon("imgs/btn_f1_selected.jpg");

// Create F1 button
final JButton btnF1 = new JButton(F1);
//btnF1.setOpaque(false);
btnF1.setContentAreaFilled(false);
btnF1.setBorder(null);
btnF1.setBorderPainted(false);
btnF1.setFocusPainted(false);
btnF1.setRolloverIcon(F1rollOver);

I attempted placing the images in the bin folder and for the creation of the background I altered the above method with regards to the declaration/fetching of the image.

public void paintComponent(Graphics g) {
        String path = "Bgnd11.jpg";
        java.net.URL imgURL = getClass().getResource(path);     
        Image img = new ImageIcon(imgURL).getImage();
        Dimension size = new Dimension(img.getWidth(observer), img.getHeight(observer));
        setPreferredSize(size);
        setMinimumSize(size);
        setMaximumSize(size);
        setSize(size);
        setLayout(null);
        g.drawImage(img, 0, 0, null);
}

I also attempted fetching the images needed for the creation of my buttons as indicated below and then passing them to my button but this did not work.

String path = "Bgnd11.jpg";
java.net.URL imgURL = getClass().getResource(path);     
Image img = new ImageIcon(imgURL).getImage();

How to locate & load the images?

Barett
  • 5,826
  • 6
  • 51
  • 55
TokTok123
  • 753
  • 3
  • 11
  • 27
  • What is your package hierarchy? – Extreme Coders May 10 '13 at 16:42
  • Only do `g.drawImage` inside `paintComponent`. And call getWidth/getHeight without observer, that is not asynchrone. – Joop Eggen May 10 '13 at 16:52
  • For better help sooner, post an [SSCCE](http://sscce.org/). But as general advice. `setPreferredSize(size); setMinimumSize(size); setMaximumSize(size); setSize(size); setLayout(null); g.drawImage(img, 0, 0, null);` Don't call any of the 1st 4 from a `paintComponent()` method. Don't set the layout to `null` ***ever*** & since `JPanel` is an `ImageObserver`, the last line should be.. `g.drawImage(img, 0, 0, this);` – Andrew Thompson May 10 '13 at 16:57
  • *"I successfully packaged it into a jar and subsequently into an .exe file."* For deploying Java desktop apps., the best option is usually to install the app. using [Java Web Start](http://stackoverflow.com/tags/java-web-start/info). JWS works on Windows, OS X & *nix. – Andrew Thompson May 10 '13 at 17:56
  • @1897Blanconeri : Hopefully [this answer](http://stackoverflow.com/a/9866659/1057230), might be of some help on the topic :-) – nIcE cOw May 19 '13 at 17:16

1 Answers1

6

In your first attempt, you're loading images from the file system, in the current directory, which is the directory from which the java of javaw command is started. That's what prevents you from bundling the images with your applications. Obviously, the end user of your app won't have the images in his current directory, and his current directory will change depending on how he launches the application.

You should instead have the images packaged inside the jar file, and thus be present in the classpath, and thus load them using the ClassLoader as you're doing in your second attempt.

Let's say they're in the folder /resources/images of the jar, which thus corresponds to the package resources.images.

Using getClass().getResource("Bgnd11.jpg"), as the javadoc indicates, tries to find Bgnd11.jpg in the same package as the class returned by getClass(). So, it would work in our example if the class was in the package resources.images. If it's not, you should use the absolute path of the resource:

URL imgURL = getClass().getResource("/resources/images/Bgnd11.jpg");   

Also, don't mess with the bin folder. This is the destination folder of Eclipse, and doing a clean build will remove everything from this directory. Just add the images to the appropriate package in the source directory, and Eclipse will automatically copy them to the destination directory when building the project.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • 1
    1+ Also to add: not to read in images from the `paint(...)` or `paintComponent(...)` methods as these methods need to be blindingly fast and need to concern themselves with drawing only and not file or resource i/o. – Hovercraft Full Of Eels May 10 '13 at 16:53
  • 3
    Agreed with Hovercraft. Setting the sizes of a component should also not be done, and certainly not from the paintComponent() method. Instead, getXxxSize() should be overridden to return the image size, in order for the layout manager to lay out this component correctly. – JB Nizet May 10 '13 at 16:55
  • 1
    @Hovercraft & JB: For reference, Andrew Thompson has been updating the [tag:embedded-resource] tag [info](http://stackoverflow.com/tags/embedded-resource/info); critical review welcome. – trashgod May 10 '13 at 19:27
  • @JBNizet .. i attempted suggestion above i.e. using the absolute path of the resource but i was not successful as the jar still does not run once after creating it .. i also stopped placing the images in the bin folder .. and referred to them from my images folder in the source directory but to no success .. any ideas as to why my images just won't show when i run the jar file? thanks – TokTok123 May 14 '13 at 11:17
  • Edit your question and show where you put the images, how you tried loading them, and what the jar file contains. – JB Nizet May 14 '13 at 13:32