使用java swing在ImageIcon代理中显示动画gif

时间:2013-04-01 13:29:48

标签: java swing jlabel imageicon animated

我曾经写过这个

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();
        }
    }
}

}

加载图像可以成功,但不会自动刷新图像 我必须通过缩放框架来渲染图像, 每次我缩放它一张图片

我读了这份文件, 它说,在其他显示我需要setImageObsever的gif 我试过,不行。并且imageIcon正常工作,没有代理打印null由getImageObserver

我也尝试阅读源代码,但我并不理解。

请帮助我,谢谢。

1 个答案:

答案 0 :(得分:1)

问题的根源可能在于ImageObserver JLabel接口的实现:

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,甚至没有调用超级实现,而实际负责调用repaint() 1}}在JLabel上刷新动画图标的新帧。此外,返回false表示我们不再对更新感兴趣。

您可以扩展JLabel以克服此约束。这是覆盖JLabel的{​​{1}}的非常简单的扩展。 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 API。