在 Swing 中显示动画 BG [英] Show an animated BG in Swing

查看:29
本文介绍了在 Swing 中显示动画 BG的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

动画(循环)GIF 可以在 JLabel 或 HTML(在 JEditorPane 等格式化文本组件中)显示,并且可以看到循环.

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

但是要加载图像作为容器的背景,我通常会使用 ImageIO.read()Toolkit.getImage()(后者当我怀念过去的千年时).两种加载图像的方法都不会导致循环图像,它通常只是第一帧.

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.

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

例如

推荐答案

使用 ImageIcon 可能是最直接的做法.需要注意以下几点:

Using ImageIcon is probably the most straightforward thing to do. A couple of things to keep in mind:

  • ImageIcon(URL) 本身利用了 Toolkit.getImage(URL).您可能更喜欢使用 Toolkit.createImage(URL) 代替 - getImage() 可以使用缓存或共享的图像数据.

  • ImageIcon(URL) itself makes use of Toolkit.getImage(URL). You may prefer using Toolkit.createImage(URL) instead - getImage() may use cached or shared image data.

ImageIcon 使用 MediaTracker 有效地等待图像完全加载.

ImageIcon makes use of a MediaTracker to effectively wait until the image is completely loaded.

因此,您的问题可能不是使用 Toolkit(ImageIO 是一个不同的野兽),而是您没有渲染完全加载的图像的事实.值得尝试的一件有趣的事情是:

So, your issue may not be the use of Toolkit (ImageIO is a different beast), but rather the fact that you're not rendering a fully loaded image. One interesting thing to try would be:

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

我的 Swing/AWT/J2D 可能有点模糊,但想法是,由于您的 ImagePanel 是一个 ImageObserver,因此可以异步通知图像信息.Component.imageUpdate() 方法应根据需要调用 repaint.

My Swing/AWT/J2D may be a bit fuzzy, but the idea is that since your ImagePanel is an ImageObserver, it can be notified asynchronously about image information. The Component.imageUpdate() method should invoke repaint as needed.

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

As noted in the comments, the call to prepareImage is not required - a working example is included below. The key is that the overridden paintComponent method invokes Graphics.drawImage, which provides the ImageObserver hook. The imageUpdate method (implemented in java.awt.Component) will continuously be invoked with the ImageObserver.FRAMEBITS flag set.

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://i.stack.imgur.com/iQFxo.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);
            }
        });
    }
}

这篇关于在 Swing 中显示动画 BG的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆