[英]Display animated gif in ImageIcon proxy with java swing
我曾经这样写
JLabel label=new JLable(URL);
frame.getContentPane().add(label);
它适用于动画gif图像
但是,当我想使用imageProxy从互联网加载gif时,它不起作用。
我的imageProxy是这个
public class ImageProxy implements Icon{
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
boolean retrieving =false;
public ImageProxy(URL url){
imageURL = url;
}
public int getIconHeight() {skip}
public int getIconWidth() {skip}
@Override
public void paintIcon(final Component c, Graphics g, int x, int y) {
System.out.println("paint");
if(imageIcon !=null){
imageIcon.paintIcon(c, g, x, y);
}else{
g.drawString("Loading image", x+10, y+80);
if(!retrieving){
retrieving =true;
retrievalThread = new Thread(new Runnable(){
public void run(){
try{
imageIcon = new ImageIcon(imageURL);
c.repaint();
}catch(Exception e){
e.printStackTrace();
}
}
});
retrievalThread.start();
}
}
}
}
它可以成功加载图像,但不会自动刷新图像。每次缩放图像时,我都必须通过缩放框来改变图像
我阅读了该文档,它说,要显示gif我需要设置我尝试过的setImageObsever,这是行不通的。 并且imageIcon正常工作,没有代理通过getImageObserver打印null
我也尝试阅读源代码,但我并没有真正理解。
请帮助我,谢谢。
问题的根源可能在于JLabel
对ImageObserver
接口的实现:
public boolean imageUpdate(Image img, int infoflags,
int x, int y, int w, int h) {
// Don't use getDisabledIcon, will trigger creation of icon if icon
// not set.
if (!isShowing() ||
!SwingUtilities.doesIconReferenceImage(getIcon(), img) &&
!SwingUtilities.doesIconReferenceImage(disabledIcon, img)) {
return false;
}
return super.imageUpdate(img, infoflags, x, y, w, h);
}
这是SwingUtilities.doesIconReferenceImage
的代码:
static boolean doesIconReferenceImage(Icon icon, Image image) {
Image iconImage = (icon != null && (icon instanceof ImageIcon)) ?
((ImageIcon)icon).getImage() : null;
return (iconImage == image);
}
如您所见,如果图标不是ImageIcon
的实例,则imageUpdate()
的结果将为false
,甚至不调用super的实现,该实现实际上负责在JLabel
上调用repaint()
来刷新动画图标的新框架。 同样,返回false
意味着我们不再对更新感兴趣。
您可以扩展JLabel
以克服此约束。 这是JLabel
的非常简单的扩展,它覆盖了imageUpdate()
。 此imageUpdate
实现的实际代码来自Component.imageUpdate()
,为简单起见, isInc
和incRate
是常量:
public static class CustomLabel extends JLabel {
private static final boolean isInc = true;
private static final int incRate = 100;
public CustomLabel(Icon image) {
super(image);
}
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int w, int h) {
int rate = -1;
if ((infoflags & (FRAMEBITS | ALLBITS)) != 0) {
rate = 0;
} else if ((infoflags & SOMEBITS) != 0) {
if (isInc) {
rate = incRate;
if (rate < 0) {
rate = 0;
}
}
}
if (rate >= 0) {
repaint(rate, 0, 0, getWidth(), getHeight());
}
return (infoflags & (ALLBITS | ABORT)) == 0;
}
}
您可以插入imageUpdate()
以添加在图像仍在加载时显示“正在加载图像”字符串的功能。
我不知道为ImageIcon
实施代理的真正原因是什么。 如果需要同步图像加载,则可以使用ImageIO
API。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.