一尘不染

Java在Swing中显示动画BG

java

动画(循环)GIF可以以JLabel或HTML格式显示(以格式的文本组件显示JEditorPane),并可以循环显示。

但是要加载图像作为容器的背景,我通常会使用ImageIO.read()Toolkit.getImage()(当我对上个千年怀旧之情时使用后者)。加载图像的两种方法都不会产生循环图像,它通常只是第一帧。

如何为背景加载动画图像?


阅读 569

收藏
2020-03-05

共1个答案

一尘不染

使用ImageIcon可能是最简单的方法。请记住以下几点:

ImageIcon(URL)本身利用Toolkit.getImage(URL)。你可能更喜欢使用Toolkit.createImage(URL)- getImage()可能使用缓存的或共享的图像数据。

ImageIcon利用MediaTracker有效地等待图像完全加载。

因此,你的问题可能不是Toolkit(ImageIO是另一种野兽)的使用,而是你没有渲染完全加载的图像。可以尝试的一件有趣的事情是:

Image image = f.getToolkit().createImage(url);
//...
ImagePanel imagePanel = new ImagePanel(image);
imagePanel.prepareImage(image, imagePanel);
//...

我的Swing / AWT / J2D可能有点模糊,但是想法是因为你ImagePanelImageObserver,所以可以异步通知有关图像信息。该Component.imageUpdate()方法应repaint根据需要调用。

编辑:

如评论中所述,prepareImage不需要调用-下面包含一个工作示例。关键是重写的paintComponent方法调用Graphics.drawImage,它提供了ImageObserver钩子。该imageUpdate方法(在中实现java.awt.Component)将在ImageObserver.FRAMEBITS设置了标志的情况下连续调用。

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class ImagePanel extends JPanel {

    private final Image image;

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

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

    public static void main(String[] args) throws MalformedURLException {
        final URL url = new URL("http://pscode.org/media/starzoom-thumb.gif");
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame("Image");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.setLocationByPlatform(true);

                Image image = f.getToolkit().createImage(url);
                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);
            }
        });
    }
}
2020-03-05