1

チェスのタイマーに問題があります。2秒2秒をカウントすることを除いて、「正常に」機能しています(2:00> 1:58> 1:56など。ただし、2秒間隔ではなく1秒間隔です)。

タイマーを定義、開始、終了するコードは次のとおりです。

private void setTime(){
    totalTime=20;
    whiteSec=0;
    whiteMin=totalTime;
    blackSec=0;
    blackMin=totalTime;
    ActionListener taskPerformer = new ActionListener() {
          public void actionPerformed(ActionEvent evt) {
              if(whiteActive){
                  if(whiteSec>0) whiteSec-=1;
                  else{
                      whiteMin-=1;
                      whiteSec=60;
                  }
                  if(whiteMin==0 && whiteSec==0) endGame();
                  else GUI.setPlayerTime(whiteMin, whiteSec);
              }else{
                  if(blackSec>0) blackSec-=1;
                  else{
                      blackMin-=1;
                      blackSec=60;
                  }
                  if(blackMin==0 && blackSec==0) endGame();
                  else GUI.setPlayerTime(blackMin, blackSec);
              }
          }
      };
    chessTimer = new Timer(1000, taskPerformer);
}

//始める

whiteActive = true;
setTime();
wCastling = true;
bCastling = true;
canEnPassant = false;
GUI.setPlayerTime(whiteMin, whiteSec); //this writes the time in some JLabels.
guiRefresh();
activePiece = null;
chessTimer.start();

//終わり

private void endGame(){
    GUI.endGame(checkMate);  //shows an endgame JOptionPane
    chessTimer.stop();
}

助けていただければ幸いです!

4

2 に答える 2

4

タイマーを2回開始できるとは思いませんが、を複数回呼び出すとsetTime()複数のタイマーが作成され、それぞれが独立してフィールドをデクリメントします(最初のタイマーがガベージコレクションされるまで、発生する場合と発生しない場合があります)。メソッドを2回続けて呼び出すと、2つのTimerオブジェクトがしばらく共存し、おそらく1秒に2回デクリメントされます。呼び出すstop()と、タイマーの1つが停止し、もう1つはそのままになります。

デバッグ手順(および全体的なグッドプラクティス)として、新しいタイマーを作成する前に、タイマーがまだないことを確認してください。

/* ... */
if (chessTimer != null) throw new IllegalStateException("setTime already called");
chessTimer = new Timer(1000, taskPerformer);

これを修正するには、重複する呼び出しを追跡するか、IllegalStateExceptionをに置き換えてバンドエイドを実行しchessTimer.stop();ます。

于 2012-12-17T07:40:17.790 に答える
1

http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.htmlから:このクラスはリアルタイムの保証を提供しません:Object.wait(long)を使用してタスクをスケジュールします方法。

于 2012-12-17T07:08:12.317 に答える