Background Image Panel

This class provides a simple means for adding a graphic as a background image to a JFrame or JPanel as there is no standard method call for doing so. The class extends JPanel so can be used anywhere an image needs to be displayed within a Swing GUI.

The panel scales the images to the available panel size and can be configured to either scale the image to fill the total available area or to honour the image's aspect ratio in which case the image is centred in the panel and is drawn at the maximum size possible that maintains the aspect ratio. Any remains space is filled with the panel's background colour.

The image will dynaimcally resize as the panel is resized.

License

This software is released under the GNU GPLv3 license


Image Panel

This class draws the image on a JPanel. To use this class see the Usage section.

/**
 * Copyright (c) 2011 Keang Ltd. All Rights Reserved.
 *
 * The ImagePanel class is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * The ImagePanel class is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with the WinDriveDetector class.  If not, see http://www.gnu.org/licenses/.
 */
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.image.ImageObserver;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

/**
 * A panel for displaying an image.
 * The image is scaled to fit the panel size whilst optionally maintaining the image aspect ratio.
 * If maintaining the aspect ratio the image is centred in the panel.
 *
 * @author Keang
 * @version 1.0 23 July 2011
 */
public class ImagePanel extends JPanel
{
private static final long serialVersionUID = 3346028388648901441L;
private Image image;
private int imgHeight;
private int imgWidth;
private final boolean maintainAspectRatio;

/**
 * Constructs an image panel from image in the file
 *
 * @param fName The file containing the image
 * @param keepAspect true to keep the images aspect ratio during scaling, false to fill the screen
 */
public ImagePanel(String fName, boolean keepAspect)
    {
    this(new ImageIcon(fName), keepAspect);
    }

/**
 * Constructs an image panel from the image
 *
 * @param img The image
 * @param keepAspect true to keep the images aspect ratio during scaling, false to fill the screen
 */
public ImagePanel(ImageIcon img, boolean keepAspect)
    {
    maintainAspectRatio = keepAspect;

    if ( img != null )
        {
        image = img.getImage();

        imgWidth = image.getWidth(this);
        imgHeight = image.getHeight(this);

        if ( imgWidth > 0 && imgHeight > 0 )
            setPreferredSize(new Dimension(imgWidth, imgHeight));
        }
    }


@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h)
    {
    if ( (infoflags & ImageObserver.ALLBITS) > 0 )
        {
        imgWidth = img.getWidth(this);
        imgHeight = img.getHeight(this);
        setPreferredSize(new Dimension(imgWidth, imgHeight));

        validate();
        repaint();
        return false;
        }

    return true;
    }

@Override
protected void paintComponent(Graphics g)
    {
    super.paintComponent(g);

    if ( image == null )
        {
        return;
        }

    Rectangle bounds = getBounds();
    int width = bounds.width;
    int height = bounds.height;

    Insets insets = getInsets();

    width = width - insets.left - insets.right;
    height = height - insets.top - insets.bottom;

    int dX1;
    int dY1;
    int dX2;
    int dY2;
    if ( maintainAspectRatio )
        {
        double wr = (double)width / imgWidth;
        double hr = (double)height / imgHeight;

        double minr = Math.min(wr, hr);

        int nW = (int)(imgWidth*minr);
        int nH = (int)(imgHeight*minr);

        if ( nW < width )
            {
            // center x dim
            dX1 = (width - nW) / 2;
            }
        else
            {
            dX1 = 0;
            }

        if ( nH < height )
            {
            // center x dim
            dY1 = (height - nH) / 2;
            }
        else
            {
            dY1 = 0;
            }

        dX2 = dX1+nW;
        dY2 = dY1+nH;
        }
    else
        {
        dX1 = 0;
        dY1 = 0;
        dX2 = width;
        dY2 = height;
        }

    g.drawImage(image, dX1, dY1, dX2, dY2, 0, 0, imgWidth, imgHeight, this);
    }
}
    

Usage

To use the class you just need to create an instance of it specifying the image to load and then add it to a Swing hierarchy as would add any other Swing component. For instance to display a JFrame with an image that fills the JFrame's display area do the following:

public class TestImagePanel
{
public static void main(String[] args)
    {
    JFrame f = new JFrame("Image Test");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    ImagePanel ip = new ImagePanel("myImage.jpg", false);
    f.add(ip);

    f.pack();
    f.setVisible(true);
    }
}
    
 
Back to the Top