繁体   English   中英

使用Java Swing在ImageIcon代理中显示动画gif

[英]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

我也尝试阅读源代码,但我并没有真正理解。

请帮助我,谢谢。

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

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。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM