Search code examples
javaswingembedded-resource

Jar won't display Images


I have problem with Image Icons. I know that this have been asked before, but I can't figure out how to fix this, becouse I think my problem is different. When I launch app with eclipse, all works. But when I make it runnable jar, it won't show images.

Some code of my ImagesHolder Class :

package Clicker;

import javax.swing.ImageIcon;

public class ImagesHolder {

       final public ImageIcon AccessoriesIcon = new ImageIcon("Images/Part_Accessories.png");
       final public ImageIcon BodyIcon = new ImageIcon("Images/Part_Body.png");
       final public ImageIcon BrakesIcon = new ImageIcon("Images/Part_Brakes.png");
       final public ImageIcon CoolingIcon = new ImageIcon("Images/Part_Cooling.png");
       final public ImageIcon ElectronicsIcon = new ImageIcon("Images/Part_Electronics.png");
       final public ImageIcon EngineIcon = new ImageIcon("Images/Part_Engine.png");
       final public ImageIcon ExaustIcon = new ImageIcon("Images/Part_Exaust.png");
       final public ImageIcon FuelIcon = new ImageIcon("Images/Part_Fuel.png");
       final public ImageIcon InteriorIcon = new ImageIcon("Images/Part_Interior.png");
       final public ImageIcon SteeringIcon = new ImageIcon("Images/Part_Steering.png");
       final public ImageIcon SuspensionIcon = new ImageIcon("Images/Part_Suspension.png");
       final public ImageIcon TransmissionIcon = new ImageIcon("Images/Part_Transmission.png");
       final public ImageIcon TiresIcon = new ImageIcon("Images/Part_Tires.png");

And If I make Images as URL, i can't reset image icons, like here (I have Labels and I want to change label icon)

Labels example :

   public JLabel AccessoriesLVL1Label = new JLabel(ImagesHolder.LockedIcon);
   AccessoriesLVL1Label.setHorizontalTextPosition(JLabel.CENTER);
        AccessoriesLVL1Label.setVerticalTextPosition(JLabel.BOTTOM);
        AccessoriesLVL1Label.setText("<html>Accessories LVL 1<br>" + "Count: " + Part.parts[1]);

And change :

if(CarMain.main[5] >=1){
            jbtnSellAccessoriesLv1.setEnabled(true);      
            Labels.AccessoriesLVL1Label.setIcon(ImagesHolder.AccessoriesIcon);         
        }

Edited: If I this :

final public ImageIcon MoneyIcon = new ImageIcon("Images/Money.png"); 

Make as :

URL MoneyIcon = ImagesHolder.class.getResource("/Money.png");

I get error in this line:

Labels.MoneyLabel.setIcon(ImagesHolder.MoneyIcon);

Error :

The method setIcon(Icon) in the type JLabel is not applicable for the arguments (URL)

Solution

  • Well, to sum up the previously given answers: I guess a potential solution would be to use classloader as Dark Knight proposed. Furthermore you just need to create a new ImageIcon before setting it.

    URL MoneyIcon = ImagesHolder.class.getResource("/Money.png");
    Labels.MoneyLabel.setIcon(new ImagesIcon(ImagesHolder.MoneyIcon));
    

    Because if you look through your code again, I guess it somewhat makes sense it does not work. I mean you want to set an ImageIcon, yet the last thing you have is an URL object. That this must throw an error should make sense. Yet as Andrew Thompson already said: You can construct an ImageIcon from that URL as displayed/explained above.

    And since you also explained that you had issues with the directories (getting the structure from source to compiled) I want to add some links for further reading: If you just use 'plain' Java (no build tools) maybe this link can help: Copying data files upon build in Java/Eclipse. It is mainly written for Eclipse, but I guess most other IDEs should provide similar options.

    From my current projects I could also recommend to use a tool like Maven. For smaller projects it might be a little over the top, but it takes of a lot of work (e.g. library handling, handling of resources like images etc.). These are just some parts that might be useful for you. If this is of interest for you I guess you will find lots of useful resources on the web since Maven (or other tools like Ant and Gradle) are quite commonly used.