2012-03-21 14 views
3

私はサイコロをアニメーション化したい、Javaで簡単なボードゲームを作っています。だから私はこのようなサイコロの写真をフラッシュ:Java Swingで再描画した後にのみイベントをトリガーしますか?

public Timer roll_dice = new Timer(50, this); 
... 
public void actionPerformed(ActionEvent evt) { 
     if(roll_dice.getDelay() > 500){ 
      roll_dice.setDelay(50); 
      roll_dice.stop(); 
      movePiece(); 
     }else{ 
      roll_dice.setDelay(roll_dice.getDelay() + 50); 
      dice_panel.repaint(0); 
     } 
    } 
} 

movePiece(){ 
    //do some more painting 
} 

ので、ダイはそう何回かのために乱数を表示した後、ゆっくりと数に落ち着くだろう。それが完了したら、movePiece()メソッドに電話したいと思います。しかし、そのままでは、再描画は散発的に起こり、サイコロが実際にアニメーション化される前にmovePiece()が呼び出されるようにすべてをねじ込みます。

誰もが、私は、最終的な再描画が発生した後にのみmovePieceを呼び出すことができますどのように任意のアイデアを持っていますか?

+1

ペイントがいつ発生するか、ペイントが発生するかどうかを完全に制御できないため、プログラムロジックがペイントに依存しないようにする必要があります。イメージを再描画して 'repaint()'を呼び出すのではなく、プログラムの起動時にイメージダイレクトイメージをImageIconに入れて、スウィングタイマーでJLabelのアイコンを交換するのはなぜですか?遅延が十分に長くなったらタイマーを止め、ブロックしたらあなたの作品を動かしてください。 –

答えて

1

ので、ダイはそう何回かのために乱数を表示した後、ゆっくりと数に落ち着くだろう。それが終わったら、私はmovePiece()メソッドを呼びたいと思います。しかし、それはそのままですが、再描画は散発的に起こり、すべてをねじ込み、ダイスロールが実際にアニメーション化される前にmovePiece()が呼び出されます。それは単にそれを行うべきではありません、そしておそらくことは、あなたが修正するために必要なものである - あなたの絵が散発的に発生している理由はここに私を心配何

です。あなたが描画をするたびにファイルからイメージを読み込んでいるのか、描画を遅くするための何か他の原因があるのだろうかと思います。この問題に関してさらに助けが必要な場合は、絵画の仕方に関する詳細を教えてください。それにかかわらず、ペインティングがいつ発生するか、あるいはペイントが発生するかどうかを完全に制御できないので、プログラムロジックがペイントに依存することを避けるべきです。

イメージを再描画してrepaint()を呼び出すのではなく、プログラム起動時にローリングダイスのイメージをImageIconに入れて、スウィングタイマーでJLabelのアイコンを交換するだけでいいのですか?遅延が十分に長くなったらタイマーを止め、ブロックしたらあなたの作品を動かしてください。

したがって、あなたはいくつかのダイスがあると仮定すると、それぞれがdiceLabelsというJLabelの配列に保持されているJLabelによって表示され、ImageIconsはdiceIconsという配列に保持されます。

public void actionPerformed(ActionEvent e) { 
    if (roll_dice.getDelay() > 500) { 
     roll_dice.setDelay(50); 
     roll_dice.stop(); 
     movePiece(); // I like this -- this shouldn't change 
    } else { 
     roll_dice.setDelay(roll_dice.getDelay() + 50); 
     // dice_panel.repaint(0); 
     for (JLabel dieLabel : diceLabels) { 
      int randomIndex = random.nextInt(diceIcons.length); 
      dieLabel.setIcon(diceIcons[randomIndex]); 
     } 
    } 
    } 

私はあなたがmovePiece()を呼び出すときに、あなたのロジックを好きで、私はこれは不変でなければならないことだと思う:次に、あなたのような何かを行うことができます。

+0

ありがとう、それは私の人生を大幅に容易にしました。 – wbarksdale

+0

@weezybizzle:あなたは大歓迎です。 –

0

あなたは)(ローリング1に現在のスレッドを別のスレッドでローリングを呼び出し、参加することができます。このようにして、メインコードはロールスレッドが終了するまで待機します(終了します)。

public void actionPerformed(ActionEvent evt) { 
    if(roll_dice.getDelay() > 500){ 
     Thread rollerThread = new RollerThread(); 
     rollerThread.start(); 
     rollerThread.join(); 
     movePiece(); 
    } 
    else{ 
     roll_dice.setDelay(roll_dice.getDelay() + 50); 
     dice_panel.repaint(0); 
    } 
} 

private RollerThread extends Thread 
{ 
    public void run(){ 
     roll_dice.setDelay(50); 
     roll_dice.stop(); 
    } 
} 

しかし、これはEDTでは動作しない可能性があります - 再描画がキューにをスケジュールする必要があるため。たぶん、あなたはSwingUtilities.invokeAndWait()を使用してイベントをsheduleすることができます:あなたはSwingUtilities.invokeLater(Runnable);movePiece();にその呼び出しを置けば

public void actionPerformed(ActionEvent evt) { 
    Thread thread = new Thread(){ 
     public void run(){ 
      if(roll_dice.getDelay() > 500){ 
       SwingUtilities.invokeAndWait(new Runnable(){ 
        public void run(){ 
         roll_dice.setDelay(50); 
         roll_dice.stop(); 
        } 
       }); 
       movePiece(); 
      } 
      else{ 
       roll_dice.setDelay(roll_dice.getDelay() + 50); 
       dice_panel.repaint(0); 
      } 
     } 
    }; 
    thread.start(); 
} 
+0

再ペイントは散発的に呼び出されるので、問題が解決するかどうかはわかりません。それだけで別のスレッドに同じ問題を移​​動しないのですか? – wbarksdale

+0

@weezybizzle編集を参照してください –

0

何が変わるのか?

if(roll_dice.getDelay() > 500){ 
    roll_dice.setDelay(50); 
    roll_dice.stop(); 

    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { movePiece(); } 
    }); 
} 
... 
関連する問題