我正在做一个我正在研究的小程序,这有一个奇怪的故障。它是像Pictionary或Charades这样的游戏的记分员/计时器。
我将从程序应该做的开始。单击Start Timer按钮可禁用Set Time,Reset Timer和Start Timer按钮,然后开始倒计时。倒计时本身在一个线程中处理,以便可以使用Timer Stop按钮停止倒计时。所有这些功能都运行正常,除了我点击开始时发生的奇怪的小图形故障:
您可以看到重置计时器按钮的“重影”出现在数字上方,并且“重置计时器”按钮上出现了一点“6”。通常会发生这种情况,但有时会出现启动计时器的幽灵,或者有时它根本就没有。这个“幽灵”在倒计时循环的下一次迭代及其后续重新绘制计时器时消失。
话虽如此,我已经将问题追踪到三个按钮的禁用状态。当我从我的代码中删除它时,没有任何故障。也许整个底部JPanel需要在禁用按钮后重新绘制?我不认为这是必要的。无论如何,我会粘贴下面的相关代码。我希望你能提供一些关于如何防止这种情况发生的建议。
public void disableButtons() {
timerStartButton.setEnabled(false);
resetTimerButton.setEnabled(false);
setTimeButton.setEnabled(false);
}
public void enableButtons() {
timerStartButton.setEnabled(true);
resetTimerButton.setEnabled(true);
setTimeButton.setEnabled(true);
}
public void timerThread(){
disableButtons();
timerRunning = true;
Thread t = new Thread(new Runnable(){
@Override
public void run(){
timerInterrupted = false;
while(timerRunning && timer > 0){
try {
timerLabel.setText(Integer.toString(timer));
timerLabel.paintImmediately(timerLabel.getVisibleRect());
Thread.sleep(1000);
} catch (InterruptedException ex) {
Logger.getLogger(ScoreTime.class.getName()).log(Level.SEVERE, null, ex);
}
timer--;
}
timerRunning = false;
if (!timerInterrupted) {
timer = 0;
timerLabel.setText(Integer.toString(timer));
if (soundOn) {
try {
//load the buzzer sound as a clip
AudioInputStream buzzerAudioIn = AudioSystem.getAudioInputStream(buzzerSoundFile);
Clip buzzerClip = AudioSystem.getClip();
buzzerClip.open(buzzerAudioIn);
buzzerClip.start();
Thread.sleep(1500);
} catch (UnsupportedAudioFileException | IOException | LineUnavailableException | InterruptedException ex) {
Logger.getLogger(ScoreTime.class.getName()).log(Level.SEVERE, null, ex);
}
}
else {
try {
Thread.sleep(1500);
} catch (InterruptedException ex) {
Logger.getLogger(ScoreTime.class.getName()).log(Level.SEVERE, null, ex);
}
}
timer = userTime;
timerLabel.setText(Integer.toString(timer));
enableButtons();
}
}
});
t.start();
}
使用Swing Timer而不是单独的Thread。
Timer将按指定的时间间隔生成事件。代码将在Event Dispatch Thread
上执行。然后你只需设置标签的文本。不需要paintImmediately(...)。
Timer还支持停止/启动方法,因此易于控制。
有关更多信息,请阅读How to Use Swing Timers上Swing教程中的部分。
您还可以查看:Program freezes during Thread.sleep() and with Timer的简单示例,只需每秒更新一次。