0

I've spend 5 hours already and have no idea why images are not loaded when running Jar.

Project structure:

Blackjack_Game
 - Source Packages
   - Images
   - blackjack
        .... classes...

At project properties I have src - Source Packages folder added by default. Tried to put images directly into the project's folder and removing /Images/, but still no help.

Inside the code I have:

dealer_url = getClass().getResource("/Images/4_of_hearts.jpg");
File img = new File(dealerCardGenerator.dealer_url.getPath());
BufferedImage bufferedImage = ImageIO.read(img);
dealerCardGenerator.imageIcon = new ImageIcon(bufferedImage);

So inside NetBeans IDE everything is OK. Fully working. But after built&clean I see no images, but all actions are done.

Can you please suggest what is wrong? Getting so mad because of this ((((

Rainy
  • 1
  • 5
  • A jar is a zip, so check the path in it. Especially it must be case-sensitive, and Windows is case insensitive, so it might run unpacked in the IDE. – Joop Eggen Jul 27 '15 at 13:32
  • Filenames in a JAR are case **sensitive**. `"/Images/4_of_hearts.jpg"` is a different file than e.g. `"/Images/4_of_hearts.JPG"` –  Jul 27 '15 at 13:35
  • As mentioned before, make sure to check for case sensitivity. Also be sure to put the files in the correct sub folder. I had this same assignment my sophomore year, and that was a problem that I encountered. – kingfrito_5005 Jul 27 '15 at 13:37
  • Thank you for replies..The path of Images folder inside JAR is at root dir: so opening JAR with winrar shows 3 folders: blackjack_game, Images, META_INF. I've also check all file names, everything seems to be correct. – Rainy Jul 27 '15 at 14:11

2 Answers2

1

A jar entry is not a file. java.io.File can only identify a file, not a jar entry. java.net.URL however can identify a jar entry using the jar: scheme, or a file using the file: scheme. That's why Class.getResource() returns a URL not a File.

Two solutions:

  • use the URL: ImageIO.read(getClass().getResource("whatever"))

  • ImageIO can also use an already-opened stream, which classloader can provide: ImageIO.read(getClass().getResourceAsStream("whatever"))

Duplicate of at least #2-4 of the questions autosuggested as related:

Community
  • 1
  • 1
dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • So am I correct that you recommend to replace e.g. dealer_url = getClass().getResource("/Images/7_of_clubs.jpg"); with something like ImageIO.read.....I will give a try, but really don't understand why this works inside the IDE but not working from executable JAR – Rainy Jul 27 '15 at 16:15
  • *"really don't understand why this works inside the IDE but not working from executable JAR"* In the IDE, the resource **is available** as a `File`, once in a Jar, it isn't. Or, from my 'copy/paste comment' .. Application resources will become embedded resources by the time of deployment, so it is wise to start accessing them as if they were, right now. An [tag:embedded-resource] must be accessed by URL rather than file. See the [info. page for embedded resource](http://stackoverflow.com/tags/embedded-resource/info) for how to form the URL. – Andrew Thompson Jul 28 '15 at 15:18
  • .. but basically, @dave_thompson_085 has completely nailed it. Note: I'd always go for the URL over a raw `InputStream`. Perhaps not relevant here, but some APIs require a **repositionable input stream** whereas the `getResourceAsStream(..)` method will often return a stream that is not repositionable. It can be fixed by wrapping the input stream in a buffered input stream, but by using an URL directly, we don't need to worry about it. Another factor is that (for example) Java's image loading ability will cache a resource from an URL, but cannot do that for a raw stream. – Andrew Thompson Jul 28 '15 at 15:23
0

Thank you all for clarifying the problem. I've realized why some functions were not working.

So the solution is to replace URL with ImageIcon:

ImageIcon i2 = new javax.swing.ImageIcon(getClass().getResource("whatever"));

and then just set icon as label icon:

jLabel1.setIcon(i2);

In this way JAR works. Previously, all methods after this icon set operation were not working, as the program was actually stopped, now everything works fine.

Rainy
  • 1
  • 5