0

I just started GUI programming in Java and I am having trouble setting the background image to a JFrame using JLabel. I have read many answers to the same question on this website but the code is too complicated for a beginner.

My source code is as follows and the image I'm using is already in src folder (I get the output window but there is no image in it):

public class staffGUI extends JFrame {
private JLabel imageLabel = new JLabel(new ImageIcon("staff-directory.jpg"));

private JPanel bxPanel = new JPanel();

public staffGUI(){
    super("Staff Management");

    bxPanel.setLayout(new GridLayout(1,1));
    bxPanel.add(imageLabel);

    this.setLayout(new GridLayout(1,1));
    this.add(bxPanel);

    this.setVisible(true);
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocationRelativeTo(null);
    this.setResizable(false);
    this.pack();
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
Charlie
  • 3,113
  • 3
  • 38
  • 60
  • 1
    What is the error you got? – Pasupathi Rajamanickam Mar 17 '15 at 04:56
  • I get the output window but there is no image in it – Charlie Mar 17 '15 at 04:59
  • 1
    *"setting the background image to a JFrame using JLabel"* I wouldn't. `JLabel` will not calculate the preferred size it needs from the child components, but only from the `text` and `icon` properties. For [example](http://stackoverflow.com/questions/22162398/how-to-set-a-background-picture-in-jpanel/22162430#22162430) (See the second example) – MadProgrammer Mar 17 '15 at 05:00
  • Your code seems to be working fine. Please check the path of the Image file. – UrsinusTheStrong Mar 17 '15 at 05:03
  • Where does `staff-directory.jpg` reside in relationship to the source – MadProgrammer Mar 17 '15 at 05:03
  • If you have the `staff-directory.jpg ` in a com package then you should give a path like this `private JLabel imageLabel = new JLabel(new ImageIcon(getClass().getResource("/com/staff-directory.jpg ")));` Try this.. – Pasupathi Rajamanickam Mar 17 '15 at 05:07
  • The image is in the same folder as the Java files.("src" folder in the project folder) – Charlie Mar 17 '15 at 05:08
  • Now it is giving me this error: Exception in thread "main" java.lang.NullPointerException at javax.swing.ImageIcon.(ImageIcon.java:217) at staffdirectory.staffGUI.(staffGUI.java:18) at staffdirectory.StaffDirectory.main(StaffDirectory.java:19) – Charlie Mar 17 '15 at 05:12
  • 1
    You need to use someting more like `new ImageIcon(getClass().getResource("/staffdirectory/staff-directory.jpg"))`. But I'd prefer to use `ImageIO` as it will at least throw an `IOException` if the image can't be loaded for some reason... – MadProgrammer Mar 17 '15 at 05:15

2 Answers2

1

ImageIcon(String) "Creates an ImageIcon from the specified file". The actual physical image is loaded in a background thread, so even though the call might return immediately, the actually loading could still be running in the background.

This means that ImageIcon does not throw any errors if the image can't be loaded, making sometimes annoying to work with. I prefer to use ImageIO.read where possible, as it will throw an IOException when it can't read a image for some reason.

The reason you image is not loading is because the image doesn't actually exist from the context of the JVM, which is looking in the current working directory of the image.

When you included resources within the context of the program, they can no longer be addressed as files and need to be loaded through the use of Class#getResource or Class#getResourceAsStream, depending on your needs.

For example

imageLabel = new JLabel(getClass().getResource("/staffdirectory/staff-directory.jpg"));

Where possible, you should supply the path to the image from the context of the source root

Can you give an example how I can use the "ImageIO.read" in my code?

import java.awt.GridLayout;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class staffGUI extends JFrame {

    private JLabel imageLabel;

    private JPanel bxPanel = new JPanel();

    public staffGUI() {
        super("Staff Management");

        imageLabel = new JLabel();
        try {
            BufferedImage img = ImageIO.read(getClass().getResource("/staffdirectory/staff-directory.jpg"));
            imageLabel.setIcon(new ImageIcon(img));
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        bxPanel.setLayout(new GridLayout(1, 1));
        bxPanel.add(imageLabel);

        this.setLayout(new GridLayout(1, 1));
        this.add(bxPanel);

        this.setVisible(true);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);
        this.setResizable(false);
        this.pack();

    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Can you give an example how I can use the "ImageIO.read" in my code? – Charlie Mar 17 '15 at 05:29
  • Is it possible to place a JButton on the JLabel image? – Charlie Mar 17 '15 at 05:38
  • So if I want to add a button at the center how do I do it? – Charlie Mar 17 '15 at 05:49
  • I'd use a `GridBagLayout`, see [Laying Out Components Within a Container](http://docs.oracle.com/javase/tutorial/uiswing/layout/index.html) for more details – MadProgrammer Mar 17 '15 at 05:53
  • I actually want four buttons at the center and I want use image icons as buttons..I just want to know if this could be implemented with the current code I'm using.. – Charlie Mar 17 '15 at 05:53
  • Yes, GridBagLayout should allow you to do this, but remember, Label determines its preferred size from the icon and text of the label, not its child components – MadProgrammer Mar 17 '15 at 07:26
0

Try this example i am sure it will work. Make sure that you have a images folder inside your src folder and put the image in it.

private JLabel imageLabel = new JLabel(getClass().getResource("/staffdirectory/staff-directory.jpg")); 

will not work and eclipse will give error as JLabel(URL) is not defined; secondly private modifier is not allowed here.

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

class BackgroundImageJFrame extends JFrame {

    private static final long serialVersionUID = 6337428393053702097L;
    JButton b1;
    JLabel l1;

    public BackgroundImageJFrame() {
        setTitle("Background Color for JFrame");
        setSize(400, 400);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setVisible(true);

        setLayout(new BorderLayout());

        JLabel background = new JLabel(
                new ImageIcon(Toolkit.getDefaultToolkit().getImage(
                        getClass().getResource("/images/free-wallpaper-4.jpg"))));
        add(background);
        background.setLayout(new FlowLayout());
        l1 = new JLabel("Here is a button");
        b1 = new JButton("I am a button");
        background.add(l1);
        background.add(b1);

        setSize(400, 400);
    }

    public static void main(String args[]) {
        new BackgroundImageJFrame();
    }
}
raghavanm
  • 13
  • 6