2017-02-06 13 views
0

GIFファイルをJLabelに表示しようとしています。私はGIFをロードし、それをラベルのアイコンとして設定しても問題ありません。しかし、今私は本当にこれが終わる時を知る必要があります。なぜなら、それはカットシーンとして機能しなければならないからです。どのような私はすでに試したことはこれです(GameSceneは、カスタムオブジェクトですが、私は私を信頼し、setIcon作品を知っている):今すぐGIFの再生が完了したことを知ります

private GameScene scene; 
private ImageIcon _temp; 
private ImageIcon toplay; 
private Thread anim; 

public Cutscene(ImageIcon gif, GameScene scene, int length){ 
    this._temp = scene.getIcon(); 
    this.toplay = gif; 
    this.scene = scene; 
    anim = new Thread(){ 
     @Override 
     public void run(){ 
      scene.setIcon(gif); 
      scene.repaint(); 
      try { 
       Thread.sleep(length); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
     } 
    }; 
} 

private void _s(){ 
    scene.setSolidColor(false); 
    scene.setIcon(toplay); 
    scene.repaint(); 
} 

public void play(){ 
    _s(); 
    anim.start(); 
} 

public void await(){ 
    try { 
     anim.join(); 
     scene.setIcon(_temp); 
    } catch (InterruptedException e) { 
     e.printStackTrace(); 
    } 
} 

、とにかくあり、私はただ与えられた量のために、プログラム全体の睡眠をさせる、これをせずに達成することができます残りのコードを続け、完全にGIFファイルを描画しないでください。

+0

"ポイントにまっすぐになる"との質問を開始するではありません。 –

+0

質問が正しく表示されますか? –

答えて

2

これは非常に単純な例です.GIFを繰り返す場合は、FRAMEBITSの要求の間の時間をテストして、ループのポイントを検出できるかどうかを判断する必要があります。

public class MonitoringLabel extends JLabel { 

    public MonitoringLabel(Icon image) { 
     super(image); 
    } 

    public void addActionListener(ActionListener listener) { 
     listenerList.add(ActionListener.class, listener); 
    } 

    public void removeActionListener(ActionListener listener) { 
     listenerList.remove(ActionListener.class, listener); 
    } 

    protected void fireActionPerformed() { 
     ActionListener[] listeners = listenerList.getListeners(ActionListener.class); 
     if (listeners.length > 0) { 
      ActionEvent evt = new ActionEvent(this, 0, "stopped"); 
      for (ActionListener listener : listeners) { 
       listener.actionPerformed(evt); 
      } 
     } 
    } 

    @Override 
    public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) { 
     boolean finished = super.imageUpdate(img, infoflags, x, y, w, h); 
     if (!finished) { 
      fireActionPerformed(); 
     } 
     return finished; 
    } 

} 

上記のクラスは、画像「終了」ローディングトリガさActionListenerを提供する(再生するアニメーションで新しいフレームそれらしない場合、これがトリガされる - 繰り返すGIFファイルがfalseを返すことはない)

必要に応じて、別のリスナー・インターフェースを使用することができます。

それを塗るときJLabelはすでに、画像にImageObserverとして、我々は手動でGIFを塗装しながら約騒ぎなしJLabelの電源を使用することができ、このように動作しているので、私はimageUpdateを上書きすることを選択した理由は...はい、私はそれをした、それは痛みです

+0

ルーピングgifは、 'FRAMEBITS'フラグが渡されるたびにカウンタをインクリメントし、フレームカウントに達したときにアクションを起動するだけで処理できます。 – teppic

+0

@teppicこれは、あなたが取得した最も簡単なものではないフレームの数を知っていると仮定します。与えられた時間 "所要時間"を "約"正しい2時間 "待つ"ことができますが、ある程度の知識があります – MadProgrammer

+0

@MadProgrammer私はこれを試してみますが、私は現在家にいません。 –

0

GIFを使用してプログラムを作成することはできますか? GIFイメージを作成するほとんどのフォトエディタでは、イメージを繰り返すかどうかを選択できます。

あなたの問題を理解していれば、gifを一度再生するように思われますか?

カットシーンの場合は、その時間にプログラムをスリープ状態にしないでください。

+0

これはまさに私のコードで見ることができるように問題ですが、ユーザーが少し寝ている間はスリープ状態になりますが、何らかの理由でプログラム全体が一時停止します。それが私のやりたいことです。しかし、これはもう少し役に立つものになっています:D –

+0

まあ、スリープは、設定された時間(ミリ秒)の間、呼び出されているポイントでプログラム全体を一時停止します。私はここで問題を完全に理解しているとは思わない。 gif自体の長さを把握する包括的なソリューションが必要な場合は、Java docsのimageObserverクラスとimageReaderクラスが役立ちます。特にこれは次のとおりです。https://docs.oracle.com/javase/7/docs/api/java/awt/image/ImageObserver.html#FRAMEBITS –

+0

@JarnoGabriëlスイングはシングルスレッドであり、 'Thread.sleep'を使用するとブロックされますメインスレッドはUIを更新できないようにします。あなたはその種の操作のためにスイングタイマーを使用する必要があります – MadProgrammer

関連する問題