Show an animated BG in Swing

Andrew Thompson picture Andrew Thompson · May 31, 2012 · Viewed 14.4k times · Source

An animated (cycling) GIF can be displayed in a JLabel or in HTML (in formatted text components like JEditorPane) and be seen to cycle.

But to load an image to paint as the background of a container, I would typically use either ImageIO.read() or Toolkit.getImage() (the latter when I'm feeling nostalgic for the last millennium). Neither method of loading an image results in a cycling image, it is typically just the first frame.

How to load an animated image for a background?

E.G.

Answer

Andrew Thompson picture Andrew Thompson · May 31, 2012

To get a cycling (animated) GIF for custom painting, one trick is to load it using an ImageIcon. While the image returned from either of the two methods listed in the question is static, one obtained from an ImageIcon is animated.

The code below will add 50 buttons, then soon after the frames of the 'zooming stars' animated GIF1 as BG to them. The ImagePanel will stretch the image to the size of the panel.

  1. It is based on this image.

Zooming Stars GIF

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.net.URL;

class ImagePanel extends JPanel {

    private Image image;

    ImagePanel(Image image) {
        this.image = image;
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image,0,0,getWidth(),getHeight(),this);
    }

    public static void main(String[] args) throws Exception {
        URL url = new URL("http://i.stack.imgur.com/iQFxo.gif");
        final Image image = new ImageIcon(url).getImage();
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                JFrame f = new JFrame("Image");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);

                ImagePanel imagePanel = new ImagePanel(image);
                imagePanel.setLayout(new GridLayout(5,10,10,10));
                imagePanel.setBorder(new EmptyBorder(20,20,20,20));
                for (int ii=1; ii<51; ii++) {
                    imagePanel.add(new JButton("" + ii));
                }

                f.setContentPane(imagePanel);
                f.pack();
                f.setVisible(true);
            }
        });
    }
}