1

我曾经写过这个

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 我尝试过,但不起作用。和 getImageObserver 没有代理打印 null 的 imageIcon 正常工作

我也尝试阅读源代码,但我不太明白。

请帮助我,谢谢。

4

1 回答 1

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

如您所见,如果图标不是will beImageIcon结果的实例,则甚至无需调用 super 的实现,该实现实际上负责调用以刷新动画图标的新框架。此外,返回意味着我们不再对更新感兴趣。 imageUpdate()falserepaint()JLabelfalse

您可以扩展JLabel以克服此限制。JLabel这是overrides的一个非常简单的扩展imageUpdate()。为简单起见,此实现的实际代码imageUpdate取自Component.imageUpdate(), 只是isIncincRate是常量:

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。如果您需要同步图像加载,您可以使用ImageIOAPI。

于 2013-04-02T05:03:44.950 回答