Where should I place resource-files like images ?

Discussion in 'Java' started by Arne Styve, Feb 20, 2006.

  1. Arne Styve

    Arne Styve Guest


    I'm building an application where I want to use buttons (JButton) with
    images loaded from files (.GIF-files).

    At the moment, I create the ImageIcon's to use like this:
    disconIcon = new ImageIcon("resources/images/discon.gif");
    lightOnIcon = new ImageIcon("resources/images/LightOn.gif");
    lightOffIcon = new ImageIcon("resources/images/LightOff.gif");

    and then use the setIcon()-method of the button to set the Icon.

    This works, but I'm not quite confortable with it.
    What is the best strategy for placing image-files so that they will always
    be found, both when running the application from within Eclipse, and when
    creating a JAR of the application for distribution ? When creating a JAR, I
    would like the image-files to be packed within the JAR. How should I refere
    to the image-files to ensure they will always be found independent of where
    my code/JAR-file is installed on the target ?

    Arne Styve, Feb 20, 2006
    1. Advertisements

  2. Arne Styve

    Cyril Guest


    Arne Styve a écrit :
    Use getClass().getClassLoader().getResource(), this way:

    disconIcon = new

    The images must be in your class path with the correct path (here


    Cyril, Feb 20, 2006
    1. Advertisements

  3. You locate the image data via the class loader. See Class.getResource()
    to get a URL, and use that URL to load the image.

    Spend a minute or two to learn about the difference between specifying
    an absolute or relative resource location from the API documentation of
    See above. getResource() uses a class loader. The default class loader
    is typically one of type URLClassLoader or similar and it resolves
    locations using the class path. Entries in the class path can be
    directories or jars. If the jar with the icons is in the class path
    (and(!) you provide the correct resource name string) the icons are
    found in the jar.

    Thomas Weidenfeller, Feb 20, 2006
  4. disconIcon = new

    or in static context or if you want to avoid subclassing changing the
    lookup of relative resources:

    disconIcon = new

    1) Class has an own getResource() method which does the work. No need to
    dereference the ClassLoader first.

    2) Class.getResource() can lock up resources relatively to the current
    class, ClassLoader.getResource() doesn't.

    Thomas Weidenfeller, Feb 20, 2006
  5. Arne Styve

    Arne Styve Guest

    Hi Thomas (and Cyril),

    Thanks for your answers. I'll try it out.

    Do you have any strategies regarding where you place resources like this ?
    Do you put them in a seperate directory, like I've suggested, or do you
    place these types of files in the same directory as the classes that uses
    them ?

    Regards Arne
    Arne Styve, Feb 20, 2006
  6. Arne Styve

    Cyril Guest


    Thomas Weidenfeller a écrit :
    Thanks for that tip. Always eager to learn ;-)


    Cyril, Feb 20, 2006
  7. It depends :)

    If you want, for example, build a self-contained component (some
    JavaBean etc.), it would make sense to have resources like icons
    relatively to the class, probably in a subdirectory "resources".

    If you have, for example, application-wide resources like application
    icons, it would make sense to have them in some absolute location, or
    relative to some main class - which would then, from an application's
    point of view, also be some kind of absolute location.


    BTW: Consider changing your quoting style. Many people on Usenet will
    already ignore you for posting the response before the quotation. It
    belongs after the quotation.
    Thomas Weidenfeller, Feb 20, 2006
  8. Arne Styve

    Arne Styve Guest

    I've studied the article at
    http://java.sun.com/j2se/1.5.0/docs/guide/lang/resources.html and I also
    found one at http://java.sun.com/docs/books/tutorial/uiswing/misc/icon.html.
    The latter one was quite detailed and good. BUT I still have the same
    problem. I've tried placing the images as subdirectories/packages under the
    package where the class is defined that uses the images, and I've tried
    placing the images at the root of the packages. It always work when I run my
    application from within NetBeans or Eclips, but as soon as I create a JAR
    with both the classes and the images, I cannot locate the image-files. I've
    followed the details in the ICON-tutorial mentioned above, but still no
    success. Is there a way to print the path from where getResource() starts to
    search from ?


    PS! Thanks for your patience..
    Arne Styve, Feb 21, 2006
  9. Arne Styve

    opalpa Guest

    Is there a way to print the path from where getResource() starts to

    say you got:

    package com.arne.util;
    class Goods {

    getResource looks from where the Goods.class file is. So if that file
    is in directory $D then the first getResource gets $D/pic.png and the
    second getResource gets $D/pix/a.png .


    opalpa, Feb 21, 2006
  10. Arne Styve

    Arne Styve Guest

    Thanks Opalinksi. I've got this to work. But when I create a JAR file with
    the class Goods in the package com.arne.util, and with the pix/a.png file
    included, I thought I still could use the same getResource("pix/a.png") when
    I start the application from the JAR-file like the following:

    c:\SomeDir\AppDir>java -cp Goods.jar Goods

    The Goods.jar file is in the c:\SomeDir\AppDir directory.

    But this does not work.
    Here is the code that gets the resource:

    java.net.URL imgURL =
    System.out.println("imgURL: " + imgURL);

    The class ProjectorButton is in the package no.hials.ProjectorControl.gui.
    The file "discon.gif" is placed at the root of the src-directory. When I use
    NetBeans, the IDE creates a "build/classes" directory in which the
    ..class-files end up in a directorystructure simelar to the package
    structure. The GIF-files are copied to the "build/classes" directory. When
    run from Netbeans this works fine. NetBeans also builds a JAR from the files
    in the "build/classes" directory, including the gif-files. The JAR file is
    placed in a new directory, named "dist" which is at the same level as the
    "build" directory. When I then open the CMD-window, and type:

    .....\dist>java -cp ProjectorManager.jar

    the application starts just fine, but the "imgURL" ends up beeing "null",
    and I'm not able to understand why.

    Any ideas, now that you've got some more details ? There must be something
    I'm missing out on here....

    Arne Styve, Feb 21, 2006
  11. Arne Styve

    opalpa Guest

    Take a peek at the contents of Goods.jar. One way to look at contents
    is to:
    "jar -ft Goods.jar"

    Does discon.gif file appear in the same directory as
    ProjectorButton.class file? Does it appear at all?
    Are they copied to correct directory? Are they put inside jar?


    opalpa, Feb 21, 2006
  12. Arne Styve

    opalpa Guest

    I want to clarify:
    The gif needs be in "build/classes/no/hials/ProjectorControl/gui"
    because that is where ProjectorButton.class is.

    The gif being in "build/classes" is not the right spot.

    After you assure this, assure the same is true about contents of jar.


    opalpa, Feb 21, 2006
  13. Arne Styve

    Arne Styve Guest

    Yes, I've tried putting them there. When in this directory and running from
    within NetBeans/Eclipse, it works fine.
    This works fine if I use .getResource("/discon.gif"); and use the
    ClassLoader instead of ProjectorControl.class.getSource().
    Yepp, when I do a "jar -ft" on my JAR-file, I find:


    The funny thing is, however, when I place the .GIF-files directly on the
    "dist"-directory (not in the JAR-file), same directory as the JAR-file is
    in, and I use the "/discon.gif", i.e. absolute reference, it works fine. It
    seems like the getResource()-method does not check the JAR-file at all.....

    Thanks for trying to help me out here. I'm really banging my head against a
    brick wall here....

    Arne Styve, Feb 21, 2006
  14. Arne Styve

    opalpa Guest

    Yepp, when I do a "jar -ft" on my JAR-file, I find:
    What about discon.gif? Also, maybe uppercase counts? I don't know
    cause I always match case.
    Are you using ProjectControl.class.getResource() or
    ProjectButton.class.getResource()? They will look things up in
    different directories. When using either one you don't want the "/"
    prefixing the paths.

    I assure you this stuff works, go through your code carefully, make a
    simple example.


    opalpa, Feb 21, 2006
  15. Arne Styve

    Arne Styve Guest

    Case doesn't seam to matter, since it works when running from classes
    (NetBeans/Eclipse runs directly from the "build" directory). But I'll make
    sure I use the same case.
    I've tried using both ProjectorButton, ProjectorControl, and the

    and printed the resulting imgURL, and seen how this makes a different. It
    all works as long as I dont run it from my JAR file.......
    I thought so too. I'll follow your advise and create a small example and run
    it through the test.

    Thanks for trying to help me out. Your support has been invaluable :)

    Arne Styve, Feb 21, 2006
  16. Arne Styve

    Roedy Green Guest

    the thing I don't like is the way you don't find out till run time if
    image is missing. I want a way making sure all images I use are in
    there and no deadwood.

    see http://mindprod.com/jgloss/cramfull.html

    Cramfull ensures all resources included in jar. It does it by
    converting your resoures into class files, that tools like GenJar can
    find using dependencies.

    See http://mindprod.com/jgloss/dependencies.html

    there should be some less drastic and memory-hungry solution that ends
    up with a traditional jar with resources.
    Roedy Green, Feb 21, 2006
  17. Arne Styve

    opalpa Guest

    Case doesn't seam to matter, since it works when running from classes
    I googled whether case matters. Case does not matter when loading from
    windows file system. Case does matter when loading from jar. Perhaps
    this is the issue. I did not write any experimets.


    opalpa, Feb 21, 2006
  18. Arne,

    People don't seem to be listening to you about how you have already
    tested your code in Eclipse and yet the same code does not work in the
    jar file despite your files being in the jar file and in the right
    location. A couple days ago in the comp.lang.java.gui newsgroup I
    posted a message about this very same problem and so far they have not
    been able to help me. I've tried all sorts of combinations of
    class.getResource() and classLoader().getResource() and still can't get
    icons to load when I use a jar file.

    If I run my jar file right above the directory where my icons exist in
    my file system then the icons load but that is only because the jar file
    is referencing the version if the icons outside of the jar instead of
    inside. One person mentioned that the icons need to be in the classpath
    but never said how or where to set the classpath. I've tried to set a
    classpath in my command window (Windows XP) and then run my jar but it
    did not help. If you get the answer please post it so I can try it in
    my environment.
    Brandon McCombs, Feb 22, 2006
  19. Arne Styve

    opalpa Guest

    What about the case thing? When loading from jar file case matters.
    When loading in windows outside of jar file case does not matter.


    opalpa, Feb 22, 2006
  20. Arne Styve

    opalpa Guest

    To be extra clear: say you have code like so:

    package experiment;
    import java.awt.*;
    import java.awt.image.*;
    import javax.imageio.*;
    import java.net.URL;
    import java.io.*;
    import javax.swing.*;
    final class GetResourcePic {
    private GetResourcePic() {}
    public static void window(final String title, final Image body)
    throws java.awt.AWTException
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    JFrame frame = new JFrame(title);
    // JFrame.setDefaultLookAndFeelDecorated(true);
    frame.getContentPane().add(new JLabel(new ImageIcon(body)));
    }); // funky
    public static void main(String a[]) throws AWTException, IOException
    URL picurl =
    BufferedImage img = ImageIO.read(picurl);
    window("GetResourcePic", img);

    with manifest file:
    Main-Class: experiment.GetResourcePic

    Make/Get an image file, name it case sensitively,GetResourcePic.gif
    (NOTE: case matters).

    Compile into classes. Move image file to same directory that contains
    GetResourcePic.class. See code run. Make jar. (check jar has all
    classes and image file in correct directory, check case sensitivity)
    See code run.

    Change gif in source to giF (NOTE: capital at end). Compile into
    classes. See code run. Make jar. See code fail.


    opalpa, Feb 22, 2006
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.