Java Tips Weblog

  • Blog Stats

    • 2,473,328 hits
  • Categories

  • Archives

Background Panel

Posted by Rob Camick on October 12, 2008

Many people want to know how to add a backgound image to a frame. The easiest way to do this is to add an image to a JLabel and then add the label to the frame. Is there a better way? Well, the answer depends on your requirements.

The code for this easy approach would be something like:

JLabel contentPane = new JLabel();
contentPane.setIcon( backgroundImage );
contentPane.setLayout( new BorderLayout() );
frame.setContentPane( contentPane );

Why does this work? Well, remember that all Swing components extend Container so you can add child components to them. However, by default, a JLabel uses a null layout so the components don’t appear. By using a BorderLayout the label can now function like a panel and be used as a content pane.

However, this approach has drawbacks:

  1. a label aways paints the image at its actual size
  2. the components added to the label must fit in the bounds of the label

So in reality it would probably only be used on fixed size windows where the size of the window is determined by the size of the image.

In most other cases we need a more flexible approach, so we need a more flexible component. Introducing, BackgroundPanel, an extension of JPanel that provides some custom painting support for the drawing of images. The basic support provided by this class allows the images to be painted in one of 3 styles:

  • scaled image (the default)
  • tiled images
  • actual sized image – the position of the image is controlled by specifying the horizontal and vertical alignment (center alignment is the default)

In addition to drawing images, this component can also be used to paint backgrounds that are not a solid colour. The Java API conveniently provides a Paint interface. A new setPaint(…) method was added to specify a Paint object to be used by the custom painting code. The Paint object can be used without an image. When both an image and a Paint object are used, the order of painting will be:

  • paint the background
  • paint using the Paint object
  • draw the image

Also, the add(…) methods have been overridden to make each component added to the panel non-opaque. After all, if you are going to all the trouble to create a fancy background you dont want your opaque panel to block the custom painting. For components that use a renderer the renderer will also need to be transparent. For example, on a JTable, you can use the following to set the alpha value of the Color to 0, which results in a transparent background colour:

table.setBackground( new Color(0, 0, 0, 0) );

Following is the the code used to create the panel displayed in the attached image:

BackgroundPanel panel = new BackgroundPanel(duke, BackgroundPanel.ACTUAL, 1.0f, 0.5f);
GradientPaint paint = new GradientPaint(0, 0, Color.BLUE, 600, 0, Color.RED);

If the above class is too complex for your requirement then you can just do basic painting of the image on the panel. A BasicBackgroundPanel class might look something like:

public class BasicBackgroundPanel extends JPanel
    private Image background;

    public BasicBackgroundPanel(Image background)
        this.background = background;
        setLayout( new BorderLayout() );

    protected void paintComponent(Graphics g)

        g.drawImage(background, 0, 0, null); // image full size
        //g.drawImage(background, 0, 0, getWidth(), getHeight(), null); // image scaled

    public Dimension getPreferredSize()
        return new Dimension(background.getWidth(this), background.getHeight(this));

Get The Code

Related Reading

Java API: java.awt.Paint

58 Responses to “Background Panel”

  1. Arasdasd said


    • Rob Camick said

      Not a very helpfull comment. Of course it works or I wouldn’t take the time to write the blog entry or post the code. It may not work the way you want it to or expect it to, but that does not make it wrong, only different. If you have a specific problem you can always sent your “demo” code by using the “Contact Us” link.

  2. Greg Blass said

    Great post here. You would not believe how many other links I looked at before I was able to use the simple 4 lines of code you posted to add a background image to a JFrame. Thanks Rob.

  3. Eli said

    Worked for me =)

    BackgroundPanel bgPanel = new BackgroundPanel(img, BackgroundPanel.SCALED, 0.0f, 0.0f);

    SCALED is so awesome, thank you! Fits the image, however you resize the frame.

  4. Garratt said

    Hey Rob, This seems like it would be perfect for what I’m trying to achieve (scaled image) but I’m having trouble. I’m wondering why use ‘Image’. From what I can tell that means I need to make another class that extends Image and defines its methods. Typically for images I use ImageIcon as it can be easily instantiated but ‘Image’ is an abstract class and therefore cannot be instantiated.
    JLabel.setIcon(new ImageIcon("resources/img.png"); Not sure how to make this class work from the example given.
    Can you please explain how I create and use the default method for the class?

    • Rob Camick said

      There is no need to use an ImageIcon to read in an Image. You can use ImageIO to read the Image. But if you really want to use an ImageIcon you can use the getImage() method to get the actual Image.

  5. James Wars said

    The BackgroundPanel does not show the image when multiples panels and a frame are used. I have a structure that starts at the top level with a JFrame ‘frame1’ then a JPanel ‘MainPanel’—(CardLayout structure) and inside the MainPanel, i have another JPanel ‘StudentPanel’ that shows yet another small sized JPanel ‘ImagePanel’ that finally add as a component the BackgroundPanel and sets it’s BorderLayout.CENTER?

    Does this mean i have to repaint and revalidate every single one of these panels?

    • Rob Camick said

      You don’t add the BackgroundPane to your ImagePanel

      You add the Image to the BackgroundPanel. Then you can add other components to the BackgroundPanel if your wish.

      If you need more help then post a proper SSCCE that demonstrates the problem. If you don’t know what a SSCCE is then search the web.


  6. Anonymous said

    Nice post. It works great and is easy to use. Love it! Thanks for all the effort that went into this.

  7. gadget00 said

    I’ve been trying to use this on a JDesktopPane, which is on top of a JFrame but so far I haven’t been able to roll it. Will it work?

    • Rob Camick said

      I don’t think you can use this panel directly on a JDesktopPane because it is designed to drag components around the pane. However, you should be able to override the paintComponent() method of your desktop panel to use the painting code found in this class.

  8. Mudassir said

    Loved this one….You solved my biggest trouble !
    Thanks a million rob !

  9. Ayaaz said

    Hey but there is one small glitch, I don’t know if that’s from my side or not… Well,the thing is when I run my code, my frame is visible with out the background image, & until I re size/minimize/maximize the frame, background doesn’t show up, why is it so ?

    • Rob Camick said

      If a component doesn’t paint until you resize the frame that is usually an indication that you added the component to the frame AFTER the frame was made visible. All components should be added to the frame BEFORE you make the frame visible.

      • Ayaaz said

        One more thing is….I think I am unable to use it on other lay-outs, except for the default layout of java swing, can u put some light on it please ?….Thanks :)

      • Rob Camick said

        I updated the source code to provide a default “preferred size” equal to the size of the image being used.

  10. Richard said

    This was a lifesaver and easy to implement! Like it so much that this is my first posting to code samples…

    Thank you!!!

    • Richard said

      Also – for folks new to Java (like me)… download the ‘’ file and drag it into the package that contains your JFrame. There’s probably other ways, but that worked for me.

  11. William said

    You sir are a true gentleman and a scholar, thank you very much for sharing this class!

  12. Paul said

    Some working code…

    public class Main {
    	public static void main(String[] args) {
    		JFrame frame = new JFrame("Test");
    		BufferedImage img = null;
    		try {
    			 File f = new File("./images/grid30x30_light.png");
    			 img =;
    			 System.out.println("File " + f.toString());
    		} catch (Exception e) {
    			System.out.println("Cannot read file: " + e);
    		BackgroundPanel background = new BackgroundPanel(img, BackgroundPanel.TILED, 0.50f, 0.5f);
    		frame.setSize(200, 100);
  13. Nikos said

    Thank you,
    this saved me a lot of time..

    In my case I wanted to add a JScrollPane with a JtextPane on a “tiled” BackgroundPanel ,but I didn’t want the background of the JTextPane to change so I just had to erase the “if” block in the “makeComponentTransparent” and everything worked fine.

    • Rob Camick said

      Glad it saved time. Instead of customizing the code you could have used the setTransparentAdd(…) method. Set it to false, add the component and then reset to true.

  14. sunil shahi said

    Thank you very much however I need 1 more help from you.. I used Paul’s code above as a demo to understand. Of course it works but I need to give the whole path of the image like “C:\\Users\\Owner\\Documents\\NetBeansProjects\\FetchMail\\src\\myPackage\\BackGround.PNG” to make it work. if I do ./myPackage/BackGround.PNG it doesnot work. Can you help me where I am doing the mistake?

  15. Bruno Pinheiro said

    Worked very well , tanks !!

  16. Sarang said

    Thank you sir, this code made my problem solve in minutes…. thanx a lot…. :)

  17. bohalloran95 said

    You have no idea how much aggravation this has saved me! Thank you!

  18. Anarcho-Willi said

    This class was indeed a great time saver for me as well. I added two different types of displaying the background images (horizontally and vertically scaled):

     * Custom painting code for drawing a SCALED_HORIZONTAL image as the
     * background
    private void drawScaledHorizontal(Graphics g) {
    	Dimension d = getSize();
    	Insets insets = getInsets();
    	int height = d.height - - insets.bottom;
    	float ratio = 1.0f * d.width / image.getWidth(null);
    	int imgHeight = (int) (image.getHeight(null) * ratio);
    	float y = (height - imgHeight) * alignmentY;
    	g.drawImage(image, 0, (int) y +, d.width, imgHeight, null);
     * Custom painting code for drawing a SCALED_VERTICAL image as the
     * background
    private void drawScaledVertical(Graphics g) {
    	Dimension d = getSize();
    	Insets insets = getInsets();
    	int width = d.width - insets.left - insets.right;
    	float ratio = 1.0f * d.height / image.getHeight(null);
    	int imgWidth = (int) (image.getWidth(null) * ratio);
    	float x = (width - imgWidth) * alignmentX;
    	g.drawImage(image, (int) x + insets.left, 0, imgWidth, d.height, null);
  19. red said

    Thanks for this great component! I think that there’s a little problem. I’ve a BagrkoundPanel p1 which renders correctly his image. p1 has a smaller child JPanel which should render a background color: in fact it doesn’t! I think that the problem is related to paintComponent… maybe at the end of method, a revalidate for all children must be invoked?

  20. This is awesome – thanks Rob!

  21. K said

    When I tried using this, I noticed it gobbling up all of my CPU and discovered that the repaint() at the end of paint_component() puts it into an infinite loop. Commenting out that call fixed the problem and everything still works fine.

    • Rob Camick said

      This class does not use the repaint() method in the paintComponent() method. You must have modified your version. Maybe try downloading the code again to make sure you have the original version.

  22. ADreaming said

    Second semester CSCI minor here. I’m using this for my final homework assignment, and I love it! Thanks for this awesome code!

  23. Josh said

    Thanks Rob! This works perfectly!

  24. Sam said

    Awesome!! Works perfectly :D Thanks for sharing

  25. bansidhe said

    Yowza! So easy, and works perfectly as far as I can tell! I love it. Thanks!

  26. Oscar Hernández said

    Thank you very much Mr. Camick, this did the trick for me.
    However, at first it “didnt work” as some people here have mentioned but after a bit of fiddling through the code I found out that it is because if you add more elements to the elements that are put inside the BackgroundPanel you have to set those to be transparent manually. Dont know if this is something that can be fixed in the actual class code though.

    Otherwise I really like it, thanks!

    • Rob Camick said

      That was a design decision that I made. I decided that only components directly added to the panel should be automatically made non-opaque. If you want everything that you add to the panel then you could customize the current code to do a recursive loop through all the components found on the panel being added.

  27. Anonymous said

    Thanks Rob. This works awesome.

  28. Deeps said

    Hi, if you set an image over a JLabel and set it in contentpane of JFrame… the how would you add other components to the same frame?

  29. Bruce said

    Your example was easy to understand, quickly educated me on what I wanted to know, and was simple to test and adapt. Thanks !

  30. Ben said

    Hi, is there any way to make this work for an animated gif?

    • Rob Camick said

      Not that I know of. You would need to use the first suggestion which is to just use the JLabel as the background and then set an appropriate layout manager.

  31. Paul said

    This worked well for me, thanks. I have some issue extending some custom classes, but thats my problem to work out.

  32. Eddie said

    Help please, I have tried this code but it seems to do nothing. What am I doing wrong?

    I only tried it on a sample code so it’s straightforward. My code:

    import java.awt.Image;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    public class Experimentals {
         * @param args the command line arguments
        public static void main(String[] args) {
            JFrame f=new JFrame();
            ImageIcon i=new ImageIcon("C:\\tester.jpg");        
    	Image img=i.getImage();;
            BackgroundPanel t=new BackgroundPanel(img);
    • Rob Camick said

      You need to add all the components to the frame BEFORE you make the frame visible. This is a Swing requirement and has nothing to do with this class. The other possible problem is that your code can’t find the image. Typically the image would be in the same directory as the class file so you don’t need the “c:\\”. Try using ImageIO to read the image. You will get an error message if the file is not found.

  33. Anonymous said

    Thanks for the help man, i tried all the other methods for placing a background on a JPanel but this has to be the simplest way to do it.

  34. TL said

    Awesome code it worked like a charm for me. I had a problem with my background not scaling properly with my JTabbedPane on my JFrame with a background image but this seems to have fixed that problem!

  35. I love English !!!! said

    You save my day. But, I have a question: How can I add other components into it when I set background as a JLabel?

    • Rob Camick said

      I don’t understand the question. The label becomes the content pane, so you add components to the frame normally. That is why you set the BorderLayout on the label.

  36. Griefed said

    This is an absolute BEAST of a class. I was bashing my head through my keyboard trying to use an image as the background for a JFrame, which would then hold a JTabbedPane. This allowed me to beautifully add a tiled image as the background.
    Thank you so much for this!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: