Question

I used to write that this

JLabel label=new JLable(URL);
frame.getContentPane().add(label);

and it works with animated gif image

however , when I want use a imageProxy to load the gif form the internet it doesn't work.

my imageProxy is this

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

}

it can success to load the image but it won't auto to refresh it image I have to chage to image by zoom the frame, every time i zoom it chage one picture

I read the document , it said that , in other to display a gif i need to setImageObsever i tried , doesn't work. and the imageIcon normal work with no proxy print null by getImageObserver

I also tried to read the souce code but i did not really understand.

Pleas help me ,thank you.

Was it helpful?

Solution

The source of the problem is probably in the implementation of ImageObserver interface by 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);
}

Here is the code for SwingUtilities.doesIconReferenceImage:

static boolean doesIconReferenceImage(Icon icon, Image image) {
Image iconImage = (icon != null && (icon instanceof ImageIcon)) ?
                   ((ImageIcon)icon).getImage() : null;
return (iconImage == image);
}

As you can see, if the icon is not instance of ImageIcon the result of imageUpdate() will be false, without even calling into super's implementation which is actually responsible to call repaint() on JLabel to refresh the new frame of the animated icon. Also, returning false means we are no longer interested in updates.

You may extend JLabel to overcome this constraint. Here is a very simple extension of JLabel that overrides imageUpdate(). The actual code for this implementation of imageUpdate is taken from Component.imageUpdate(), just isInc and incRate are constants for simplicity:

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

You may plug into imageUpdate() to add the functionality of displaying "Loading image" string while image is still loading.

I wonder what is the real reason behind the implementation of proxy for ImageIcon. If you need synchronous image loading you can use ImageIO API.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top