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

}

画像の読み込みには成功しますが、画像を自動的に更新することはできません。ズームするたびに、フレームをズームして画像に変更する必要があります。画像を 1 つ変更します。

ドキュメントを読んだところ、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);
}

ご覧のとおり、アイコンがImageIconの結果のインスタンスでない場合は、アニメーション化されたアイコンの新しいフレームをリフレッシュするために実際に呼び出すスーパーの実装を呼び出すことさえありませimageUpdate()ん。また、戻るということは、更新に関心がなくなったことを意味します。 falserepaint()JLabelfalse

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。同期的な画像の読み込みが必要な場合は、ImageIOAPI を使用できます。

于 2013-04-02T05:03:44.950 に答える