国际象棋秒表不规则地工作

时间:2012-12-17 07:01:15

标签: java swing timer

我在国际象棋中遇到计时器问题。它工作“很好”,除了它计算两个二分之一(2:00> 1:58> 1:56等等......但这是1秒间隔,而不是2秒间隔)

这里是我定义,开始和结束计时器的代码:

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

我很感激任何帮助!

2 个答案:

答案 0 :(得分:4)

虽然我不相信Timer可以启动两次,但是多次调用setTime()会产生多个定时器,每个定时器都会独立递减字段(直到第一个被垃圾收集,这可能会也可能不会发生)。如果连续两次调用该方法,则两个Timer对象将共存一段时间,并且它可能每秒递减两次;调用stop()会阻止其中一个计时器并保持另一个计时器。

作为调试步骤(以及整体的良好做法),在创建新计时器之前检查您是否还没有计时器:

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

要解决此问题,请通过将{IllegalStateException替换为chessTimer.stop();来跟踪重复的调用或对其进行创可贴。

答案 1 :(得分:1)

来自http://docs.oracle.com/javase/1.4.2/docs/api/java/util/Timer.html

:此类不提供实时保证:它使用Object.wait(long)方法调度任务。