Search code examples
javaswingjpanelbackground-imagepaintcomponent

Java - JPanel with background image AND normal functionality


I've been looking around and working on making a JPanel able to have an image background. I know there is a ton of information reguarding this ( example 1 and example 2 ). Neither of these are exactly what I'm looking for.

What I am looking for, is a way to just add a function or the functionality to set a background image on a JPanel while maintaining everything else. The problem that I have right now is that I have a few classes that extend JPanel and when I change them to extend my new ImagePanel class, the constructor fails (obviously, the parameters are different). I have the constructor for one of those files going super( new BorderLayout() ); and the only way I can get it to function so far is to ditch either the layout, or the background image. I can't get both to work together.

Here's the latest desperate attempt:

import java.awt.*;
import javax.swing.JPanel;

class ImagePanel extends JPanel {

  private Image img;

  public ImagePanel(Image img, LayoutManager layout) {
    this.img = img;
    Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
    setPreferredSize(size);
    setMinimumSize(size);
    setMaximumSize(size);
    setSize(size);
    setLayout(null);
    super.setLayout(layout);
  }

  public void paintComponent(Graphics g) {
    g.drawImage(img, 0, 0, null);
  }

}

If anyone could help me out, or point me towards what I'm looking for, that would be great. I don't need any super crazy functionality like background scaling or anything like that. I just want an image to be the background, and for it to maintain its functionality in all other ways.

Thanks.


Solution

  • If you're open to suggestions, you might consider a JLayeredPane.

    These containers have layers, and each layer is capable of storing components.
    So, you may have a JPanel, or JLabel for that matter, with your background image on the bottom layer, and place whatever else on another JPanel, in a higher layer.

    If you want to stick to your ImagePanel, you probably should call super.paintComponent as well.

    class ImagePanel extends JPanel {
            ...
    
        public void paintComponent(Graphics g) {
            super.paintComponent(g);
            g.drawImage(img, 0, 0, this);
        }
    }