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

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

}

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

我阅读了文档, 它说,在其他情况下显示 gif 我需要 setImageObsever 我试过了,没用。并且 imageIcon 在没有代理的情况下正常工作,通过 getImageObserver 打印 null

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

请帮帮我,谢谢。

最佳答案

问题的根源很可能是在JLabel实现ImageObserver接口(interface)上:

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(),为简单起见,仅 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实现代理的真正原因是什么。如果您需要同步图像加载,可以使用ImageIO API。

关于java - 使用 java swing 在 ImageIcon 代理中显示动画 gif,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15744415/

相关文章:

java - Twitter4j - 超出速率限制

java - 使用 "in"修饰符编写 MongoDB 查询

java - 在 JEditorPane 中突出显示

java - 测试 JLabel 是否需要更改大小

java - ArrayList<JPanel> 计算器 GUI 的 NullPointerException

Java - JLabel 背景不是完全透明的?

java - 如何在 JLabel 中插入 JPanel?

java - 改变落球速度...处理中

java - mongo问题中的QueryBuilder和 'in'方法

java - 在 Java 中使用 swing 实现猜词游戏需要帮助吗?