動畫(循環)GIF可以以JLabel
或HTML(格式化文本組件,如JEditorPane
)顯示,並可看作循環。在Swing中顯示動畫BG
但是要加載圖像作爲容器的背景進行繪製,我通常會使用ImageIO.read()
或Toolkit.getImage()
(後者當我懷念上一個千年時)。加載圖像的方法都不會產生循環圖像,通常只是第一幀。
如何加載一個動畫圖像的背景?
動畫(循環)GIF可以以JLabel
或HTML(格式化文本組件,如JEditorPane
)顯示,並可看作循環。在Swing中顯示動畫BG
但是要加載圖像作爲容器的背景進行繪製,我通常會使用ImageIO.read()
或Toolkit.getImage()
(後者當我懷念上一個千年時)。加載圖像的方法都不會產生循環圖像,通常只是第一幀。
如何加載一個動畫圖像的背景?
使用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);
//...
我的揮杆/ AWT/J2D可能有點模糊,但這個想法是,既然你ImagePanel
是ImageObserver
,它可以異步關於圖像信息通知。如果需要,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);
}
});
}
}
要獲得用於自定義繪畫的自行車(動畫)GIF,一個技巧是使用ImageIcon
加載它。雖然從問題中列出的兩種方法之一返回的圖像是靜態的,但從ImageIcon
獲得的圖像是動畫的。
下面的代碼將添加50個按鈕,然後不久將'縮放星'動畫GIF 的幀作爲BG給它們。 ImagePanel
會將圖像拉伸至面板的大小。
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);
}
});
}
}
張貼[SSCCE](http://sscce.org/) – mKorbel
感謝這個整潔的SSCCE,我不知道ImageIcon能夠顯示.gif的動畫。我在辯論是否應該爲我的GUI添加一個動畫圖片,現在我知道如果我想添加它,它會相當簡單。 – WilliamShatner
我設法讓gif動畫我的JPanel裏面是這樣的:
private JPanel loadingPanel() {
JPanel panel = new JPanel();
BoxLayout layoutMgr = new BoxLayout(panel, BoxLayout.PAGE_AXIS);
panel.setLayout(layoutMgr);
ClassLoader cldr = this.getClass().getClassLoader();
java.net.URL imageURL = cldr.getResource("img/spinner.gif");
ImageIcon imageIcon = new ImageIcon(imageURL);
JLabel iconLabel = new JLabel();
iconLabel.setIcon(imageIcon);
imageIcon.setImageObserver(iconLabel);
JLabel label = new JLabel("Loading...");
panel.add(iconLabel);
panel.add(label);
return panel;
}
這種方法的幾點:
1.圖像文件是罐子內;
2. ImageIO.read()返回一個BufferedImage,它不更新ImageObserver;
3.查找捆綁在jar文件中的圖像的另一種方法是要求Java類加載器(加載程序的代碼)獲取文件。它知道事情在哪裏。
因此,通過這樣做,我能夠在我的JPanel中獲得我的動畫gif,並且它像一個魅力一樣工作。
很棒。測試過'Toolkit.createImage(URL)'作爲'new ImageIcon(url).getImage()'的直接「插入式」替代品,圖片也被循環使用。請注意,我並不打算調用'prepareImage'。 –
明天我會編輯我的回覆,但我也注意到我創建的測試(您的代碼的修改版本)不需要prepareImage調用。我相信對Graphics.drawImage的調用提供了ImageObserver鉤子... – kschneid
只注意到剛纔的編輯。我認爲這可能是我的第一個規範問答,但事實證明你的答案更好!我不確定是否被激怒或被高估找到更多細節。 (再多考慮一下..)好吧,我很高興。感謝您的回答。 :) –