在 Swing 中显示动画 BG [英] Show an animated BG in Swing
问题描述
动画(循环)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 ofToolkit.getImage(URL)
. You may prefer usingToolkit.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屋!