Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / February 2006

Tip: Looking for answers? Try searching our database.

Where should I place resource-files like images ?

Thread view: 
Arne Styve - 20 Feb 2006 11:12 GMT
Hi,

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 ?

Regards
Arne
Cyril - 20 Feb 2006 11:34 GMT
Hi,

Arne Styve a écrit :
> 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 ?

Use getClass().getClassLoader().getResource(), this way:

disconIcon = new
ImageIcon(getClass().getClassLoader().getResource("resources/images/discon.gif"));

The images must be in your class path with the correct path (here
resources/images).

Cheers,

Cyril
Thomas Weidenfeller - 20 Feb 2006 12:26 GMT
> disconIcon = new
> ImageIcon(getClass().getClassLoader().getResource("resources/images/discon.gif"));

disconIcon = new
ImageIcon(getClass().getResource("resources/images/discon.gif"));

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

disconIcon = new
ImageIcon(<the-class-name>.class.getResource("resources/images/discon.gif"));

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
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Cyril - 20 Feb 2006 12:49 GMT
Hi,

Thomas Weidenfeller a écrit :
> 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.

Thanks for that tip. Always eager to learn ;-)

Cheers,

Cyril
Thomas Weidenfeller - 20 Feb 2006 12:16 GMT
> 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 ?

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
getResource().

> 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 ?

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
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Arne Styve - 20 Feb 2006 12:35 GMT
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

>> What is the best strategy for placing image-files so that they will
>> always be found, both when running the application from within Eclipse,
[quoted text clipped - 18 lines]
>
> /Thomas
Thomas Weidenfeller - 20 Feb 2006 13:42 GMT
> 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?

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.

/Thomas

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.
Signature

The comp.lang.java.gui FAQ:
ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq
http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/

Arne Styve - 21 Feb 2006 11:08 GMT
>> 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
[quoted text clipped - 7 lines]
>
> /Thomas

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 ?

-Arne

PS! Thanks for your patience..
opalpa@gmail.com opalinski from opalpaweb - 21 Feb 2006 12:31 GMT
> Is there a way to print the path from where getResource() starts to
> search from ?

say you got:

package com.arne.util;
class Goods {
...
  Goods.class.getResource("pic.png");
  Goods.class.getResource("pix/a.png");
...
}

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 .

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
Arne Styve - 21 Feb 2006 13:01 GMT
<opalpa@gmail.com> wrote in message
news:1140525098.780296.146240@z14g2000cwz.googlegroups.com...
>> Is there a way to print the path from where getResource() starts to
>> search from ?
[quoted text clipped - 16 lines]
> opalpa@gmail.com
> http://www.geocities.com/opalpaweb/

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 =
ProjectorButton.class.getResource("discon.gif");
       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
no.hials.ProjectorControl.gui.ProjectorControl

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
opalpa@gmail.com opalinski from opalpaweb - 21 Feb 2006 13:44 GMT
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?

> The GIF-files are copied to the "build/classes" directory.

Are they copied to correct directory?  Are they put inside jar?

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
opalpa@gmail.com opalinski from opalpaweb - 21 Feb 2006 13:48 GMT
I want to clarify:

> The GIF-files are copied to the "build/classes" directory.

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.

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
Arne Styve - 21 Feb 2006 14:22 GMT
<opalpa@gmail.com> wrote in message
news:1140529699.002734.250980@f14g2000cwb.googlegroups.com...
>I want to clarify:
>
>> The GIF-files are copied to the "build/classes" directory.
>
> The gif needs be in "build/classes/no/hials/ProjectorControl/gui"
> because that is where ProjectorButton.class is.

Yes, I've tried putting them there. When in this directory and running from
within NetBeans/Eclipse, it works fine.

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

This works fine if I use .getResource("/discon.gif"); and use the
ClassLoader instead of ProjectorControl.class.getSource().

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

Yepp, when I do a "jar -ft" on my JAR-file, I find:

no/hials/ProjectorControl/gui/LightOff.GIF
no/hials/ProjectorControl/gui/LightOn.GIF
no/hials/ProjectorControl/gui/ProjectorButton.class

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
opalpa@gmail.com opalinski from opalpaweb - 21 Feb 2006 14:58 GMT
> Yepp, when I do a "jar -ft" on my JAR-file, I find:

> no/hials/ProjectorControl/gui/LightOff.GIF
> no/hials/ProjectorControl/gui/LightOn.GIF
> no/hials/ProjectorControl/gui/ProjectorButton.class

What about discon.gif?  Also, maybe uppercase counts?  I don't know
cause I always match case.

> This works fine if I use .getResource("/discon.gif"); and use the
> ClassLoader instead of ProjectorControl.class.getSource().

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.

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
Arne Styve - 21 Feb 2006 15:37 GMT
<opalpa@gmail.com> wrote in message
news:1140533933.768316.82030@g44g2000cwa.googlegroups.com...
>> Yepp, when I do a "jar -ft" on my JAR-file, I find:
>
[quoted text clipped - 4 lines]
> What about discon.gif?  Also, maybe uppercase counts?  I don't know
> cause I always match case.

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.

>> This works fine if I use .getResource("/discon.gif"); and use the
>> ClassLoader instead of ProjectorControl.class.getSource().
[quoted text clipped - 3 lines]
> different directories.  When using either one you don't want the "/"
> prefixing the paths.

I've tried using both ProjectorButton, ProjectorControl, and the
ClassLoader.getSystemClassLoader().getResource()

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 assure you this stuff works, go through your code carefully, make a
> simple example.

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
opalpa@gmail.com opalinski from opalpaweb - 21 Feb 2006 20:20 GMT
> 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 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.

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
Brandon McCombs - 22 Feb 2006 00:34 GMT
> <opalpa@gmail.com> wrote in message
> news:1140533933.768316.82030@g44g2000cwa.googlegroups.com...
[quoted text clipped - 31 lines]
>
> -Arne

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.
opalpa@gmail.com opalinski from opalpaweb - 22 Feb 2006 02:02 GMT
What about the case thing?  When loading from jar file case matters.
When loading in windows outside of jar file case does not matter.

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
opalpa@gmail.com opalinski from opalpaweb - 22 Feb 2006 02:23 GMT
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.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
       frame.getContentPane().add(new JLabel(new ImageIcon(body)));
       frame.pack();
       frame.setLocationRelativeTo(null);
       frame.setVisible(true);
     }
   }); // funky
 }
 public static void main(String a[]) throws AWTException, IOException
{
   URL picurl =
GetResourcePic.class.getResource("GetResourcePic.gif");
   System.out.println(""+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.

Opalinski
opalpa@gmail.com
http://www.geocities.com/opalpaweb/
Brandon McCombs - 22 Feb 2006 02:59 GMT
> What about the case thing?  When loading from jar file case matters.
> When loading in windows outside of jar file case does not matter.
>
> Opalinski
> opalpa@gmail.com
> http://www.geocities.com/opalpaweb/

I changed the case of my filenames in my code and it worked.  When i
created the files MS Paint made them have uppercase file extensions and
that's also how eclipse was looking at them so I had to refresh the
images/ folder in eclipse after I renamed the files to .gif from .GIF.

thanks Opalinski. I've been working on this for a couple weeks now off
and on and no one could ever figure it out to help.
Arne Styve - 22 Feb 2006 09:51 GMT
<opalpa@gmail.com> wrote in message
news:1140573302.829486.51580@g44g2000cwa.googlegroups.com...
> What about the case thing?  When loading from jar file case matters.
> When loading in windows outside of jar file case does not matter.
>
> Opalinski
> opalpa@gmail.com
> http://www.geocities.com/opalpaweb/

THANK YOU!! You made my day!!

You were absolutely correct. Case DOES matter. The extra anoying part here
(since working in a M$ environment) is that we use Microsoft SourceSafe to
manage our sourcefiles, and of some reason SourceSafe keeps changing the
case on directories and file extensions now and then.....

I renamed from .GIF to .gif, and it worked.....

Thanks!

-Arne
steve - 22 Feb 2006 22:29 GMT
>> <opalpa@gmail.com> wrote in message
>> news:1140533933.768316.82030@g44g2000cwa.googlegroups.com...
[quoted text clipped - 52 lines]
> did not help.  If you get the answer please post it so I can try it in
> my environment.

yep that's what i find , when my programs don't work.
it's every body else's fault for not listening.

but then I wake up from my dream.

The following  code works ( i know because i use it every day)

YOU DO NOT NEED ANY CLASS PATH TO POINT TO YOUR IMAGES IN YOUR ENVIRONMENT,
nor do they need to be on the "class path"

public class MyProvidesReports implements ProvidesReports {

some other code here........
     Getpictures(JobParams);
some other code............

 private void Getpictures(HashMap ReportParams) {
     java.net.URL Source;
     java.net.URL Source1;

     Source = MyProvidesReports.class.getResource("/Images/Image1.png"); //
this is a fixed format for all java platforms do not use "file.separator
    // Source1 = MyProvidesReports.class.getResource("/Images/Chop.png"); //
this is a fixed format for all java platforms do not use "file.separator

    // ReportParams.put("MyChop", Source1);
     ReportParams.put("CompanyLogo", Source);
 }

}
you just need to compile the pictures into a directory

"/Images/Image1.png"

BUT NOTE:
THE CHARACTER CASE, not all platforms ignore the case , "Images" is NOT the
same as "images"  

ALSO NOTE
Do not use "file.separator" or strings with paths in, because file separators
are different on each platform.

use the URL class, and a standard separator and it will always work.

the above code is for getting pictures so that their references can be passed
to reports or buttons or whatever.

those  3-5 lines , will save your life every time, on every platform i have
yet tested it on   ( windows95/98/se/2000/NT/linux/osx/solaris/yellowdog)
Roedy Green - 21 Feb 2006 17:06 GMT
>This works, but I'm not quite confortable with it.

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
http://mindprod.com/jgloss/genjar.html

there should be some less drastic and memory-hungry solution that ends
up with a traditional jar with resources.
Signature

Canadian Mind Products, Roedy Green.
http://mindprod.com Java custom programming, consulting and coaching.



Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.