Java Swing在禁用按钮时显示毛刺

问题描述 投票:0回答:1

我正在做一个我正在研究的小程序,这有一个奇怪的故障。它是像Pictionary或Charades这样的游戏的记分员/计时器。

我将从程序应该做的开始。单击Start Timer按钮可禁用Set Time,Reset Timer和Start Timer按钮,然后开始倒计时。倒计时本身在一个线程中处理,以便可以使用Timer Stop按钮停止倒计时。所有这些功能都运行正常,除了我点击开始时发生的奇怪的小图形故障:

enter image description here

您可以看到重置计时器按钮的“重影”出现在数字上方,并且“重置计时器”按钮上出现了一点“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();
}
java swing button repaint display
1个回答
1
投票

使用Swing Timer而不是单独的Thread。

Timer将按指定的时间间隔生成事件。代码将在Event Dispatch Thread上执行。然后你只需设置标签的文本。不需要paintImmediately(...)。

Timer还支持停止/启动方法,因此易于控制。

有关更多信息,请阅读How to Use Swing Timers上Swing教程中的部分。

您还可以查看:Program freezes during Thread.sleep() and with Timer的简单示例,只需每秒更新一次。

© www.soinside.com 2019 - 2024. All rights reserved.