Hi there,

In the code below my ImageIcon isn't showing when I run the program. I always struggle with adding Images in my GUIs and it's irritating. Is there some all important rule that I should know or something?

//Create window Components
	JLabel lblrequest = new JLabel("Enter amount of square meters:");
	JTextField inpt = new JTextField(10);
	JButton btnEnter = new JButton("Enter");
	JButton btnClear = new JButton("Clear");

	JLabel lblAdhesive = new JLabel("Adhesive:");
	JLabel AdhOutput = new JLabel("0 X 20kg bags.");
	JLabel lblGrout = new JLabel("Grout:");
	JLabel GrtOutput5 = new JLabel("0 X 5kg bags.");
	JLabel GrtOutput20 = new JLabel("0 X 20kg bags.");
	ImageIcon image = new ImageIcon("NationalTile.png");
	public Container createContentPane(){
		//Add window Components
		JPanel imagePanel = new JPanel();
		imagePanel.setLayout(new FlowLayout());
		JLabel imgLabel = new JLabel(image);
		JPanel topPanel = new JPanel();
		topPanel.setLayout(new FlowLayout());

		JPanel textPanel = new JPanel();
		JPanel btnPanel = new JPanel();
		JPanel AdhesivePanel1 = new JPanel();
		AdhesivePanel1.setLayout(new FlowLayout());
		JPanel AdhesivePanel2 = new JPanel();
		JPanel GroutPanel1 = new JPanel();
		GroutPanel1.setLayout(new FlowLayout());
		JPanel GroutPanel2 = new JPanel();
		JPanel GroutPanel3 = new JPanel();
		//Add panels to Container
		Container c = getContentPane();
		c.setLayout(new GridLayout(10,1));
		return c;

Thanks for taking a look at this!
*Just let me know if you want to see the rest of the code, sure it won't be needed though..

Suggest you try testing "image" to see if it's null just before line 19. There are often problems with file names & default directories when reading images (or any other files).

ps: I don't understand why you have so many JPanels, a lot of them have only 1 component in them, so why bother?

Cool I'll try testing it then. If it comes back 'negative' what would the most likely causes be that it's not working? just Filenames that might be spelled wrong or something?

I used lots of panel (I know it looks like crap) becauase I struggled getting a proper LayoutManager that will display all the components right underneath each other centered.. If you know of a better LayoutManager other than GridLayout please let me know? It's not fun working with that many Panels..

1 Yes, file names or (more common) paths
2 GridBagLayout - it looks hard because its got so many options, but it's where most people end up, sooner or later.
Anyway, a 1 component panel doesn't help layout, just add the component wherever you would have added the panel!

Ahh! *Epiphany* okay cool.. For some reason I thought that all components should be inside a panel before you add it to the container? Guess not..

I had a look at GridBagLayout, looks very complicating. I'll read up on it some more then and try it out.

It's so easy to fall into that kind of trap, we've all done it. One assumes, without even explicitly thinking about it, that X is necessary, so you always use it, and never discover that it's not.

The official tutorial on GridBagLayout is a good place to start. Once you've used it a couple of times you build up a little collection of examples that you can just copy/paste in future projects. IMHO its the only layout manager to use if you're serious about GUI appearance.

new ImageIcon(String fileName) is a real pet hate of mine. Throws no exceptions, just silently returns a null. Then JLabel silently accepts null as an image parameter (ie "no image"), and hew presto! no image, and you have zero diagnostics.
Why oh why doesn't it throw a file not found exception?

Thanks for the link on the GridBagLayout Tutorial! Will deffinately work through that just now.
So about the ImageIcon thing, if the filename is correct and the path is correct(its in the same directory as the .class file) and it still doesn't work then that means I'm pretty screwed? ...So frustrating.
Is the only option ImageIcon to put images in a GUI? Otherwise I'll try something else..

No, not screwed. Not at all. ImageIcons in JLabels definitely work. I use them all the time to display images. Sometimes you have to be a bit persistent to get the file reference right.
Have you confirmed that the ImageIcon is null yet? It may be a likely cause, but it could still be something else altogether.

Try printing
(new File("NationalTile.png")).getCanonicalPath();
to see exactly what/where Java is looking for

Hi mate - i used to have the same problem with images. However I think I have got them worked out now. Say you want to load an image onto a panel - you can either create a JLabel and add the icon to the label or you can paint the image onto the screen using the paint method.

You can use this method for an icon:

/** Returns an ImageIcon, or null if the path was invalid. */
    protected static ImageIcon createImageIcon(String path, String description) 
        java.net.URL imgURL = ImageFrame.class.getResource(path);
        if (imgURL != null) 
            return new ImageIcon(imgURL, description);
        } else {
            System.err.println("Couldn't find file: " + path);
            return null;

And the second method you paint the image onto the screen. Does this help at all?

I'm at work at the moment and here the PC that I'm working on can barely open notepad. Never mind install the JDK and run cmd prompt etc. So I'm going to have to wait till I get home to try this out..

But I'll go try the getCanonicalPath() thing and see what happens. I don't if this could be a factor: I'm using Eclipse on this thing. And what I thought I should do is just go to the folder on my PC that stores the .java and .class file (the workflow directory that Eclipse creates) and paste the image in there.

Don't know then if eclipse is messing this up then..

Thanks Katana24! As I said I don't have access to a PC with the JDK on now but I will deffinately try out your advice as soon as I can. :-)

Hi Katana
That's a useful piece of code. At least you get an error message! Since the main use for ImageIcons is to put them in JLabels, maybe it would be neat to go one step further and return a populated JLabel?

Using paintComponent(...) (not paint(...)!) is appropriate for putting an image as a background in a window, but is a bit of a techy hack for just displaying a non-overlapped image

Edit: ps You could use the new File/CanonicalPath thing to improve the diagnostic
System.err.println("Couldn't find file: " + path);
so you know explicitly where Java was actually looking for the file

I don't if this could be a factor: I'm using Eclipse on this thing. And what I thought I should do is just go to the folder on my PC that stores the .java and .class file (the workflow directory that Eclipse creates) and paste the image in there. Don't know then if eclipse is messing this up then..

It's not that simple (is it ever?). Java looks for files that have a relative path name (like your example) in the

current user directory. This directory is named by the system property user.dir, and is typically the directory in which the Java virtual machine was invoked.

This is far from obvious when you are using an IDE. I'm still putting my money on a path problem.

Geez.. so much trouble just for adding an image, I don't want to hack into NASAS satalites or anyting, just want a stupid image to display. Why could it just be more like HTML (<img src="theImage.png"/> and there you go? Ohwel.. Thanks for all the help, I'll try and crack this thing tonight then.

ps If the file is in the same directory as the .class files, try prefixing the name with a /, as in "/NationalTile.png"

Cheers James for that advice its just what Im used to using for painting images and the like. Btw Dean I use Eclipse too and I found it to be a tad annoying at first but in order to get an image and use it in a particular class you need to move the image into the package that you are using or if you are using a txt file you move it into the overall project you are using.

hope this helps

Re where to put images(esp.in Eclipse), here's what I do...
I create a folder called images in the project, at the same level as the top-level packages. Then all my images are referred to as "/images/whatever.bmp" etc.
Then when I build the jar, I just leave that folder checked to include it in the jar and all my images load correctly when the jar is run. I seem to remember starting doing this long ago when I read somewhere that it's a widespread convention, but I can't prove that now.
Either way, the initial "/" on the path (or not) is critical.