使用计时器进行倒计时

4

尝试编写一个计时器来进行倒计时(像火箭发射:3-2-1-Go)。但我所编写的似乎只执行一次。我需要它重复(几乎是递归地)执行,直到值达到0。

正如您所见,我有各种println语句来跟踪此过程的进展。这是我的输出:

在Coundown构造函数中

在ActionListener中

倒数计时

3

错误在于我缺少以下输出:

2

1

Go

这告诉我这个计时器实际上没有在倒计时。它似乎在等待一秒钟然后终止。

我如何才能让它在计时器达到零之前自我调用?谢谢!

public class StopWatch {

    JFrameMath myTest;
    int seconds;

    /* Constructor */
    public StopWatch(JFrameMath thisTest, int sec) {
        myTest = thisTest;
        seconds = sec;

        myTest.hideTestButtons(true);
        Countdown display = new Countdown(myTest);
    }
}

class Countdown extends JFrame implements ActionListener {

    private Timer myTimer = new Timer(250, this);
    JFrameMath myTest;

    public Countdown(JFrameMath thisTest) {

        System.out.println("in Coundown constructor");  

        myTimer.setInitialDelay(1150);
        myTest = thisTest;
        myTimer.start();
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        System.out.println("in ActionListener");      
        int countSeconds = 3;

        if(countSeconds == 0) {
            myTest.showTimeRemaining("Go");
            myTimer.stop();
            System.out.println("done");
        } else {
            System.out.println("counting down");
            myTest.showTimeRemaining(""+countSeconds);
            countSeconds--;
        }

        myTimer.stop();
        myTest.hideTestButtons(false);
    }
}

public void showTimeRemaining(JFrameMath thisTest, String numSec) {
  System.out.println(numSec);
    lblCountdown.setText(numSec);
    thisTest.pack();
}

Timer 的完整类型是什么? - João Silva
2
@João:可能是javax.swing.Timer - Mechanical snail
抱歉,我没有看到这个。我有一个import javax.swing.*,但没有其他进一步标识其类型的内容,它必须是javax.swing.Timer,就像Mechanical snail所说的那样。 - AndroidDev
2个回答

6
actionPerformed的结尾中myTimer.stop()。这是防止触发后续事件的原因。你只想在if (countSeconds == 0)内调用stop
此外,我不知道这是一个打字错误还是测试,但你需要从actionPerformed中删除int countSeconds = 3;这一行。

谢谢,这样做可以了。现在我在输出控制台中得到了正确的输出,但是它还没有完全正确。首先,输出没有像我需要的那样每隔一秒分隔开。其次,更重要的是,我的JLabel没有反映出递减的输出。它从“3”开始,一直保持不变,直到消失。有什么想法吗?再次感谢! - AndroidDev
1
  1. 如果你想让事件延迟一秒后触发,你需要在Timer构造函数中定义一个中间延迟时间为1000,即new Timer(1000, this)。请注意,setInitialDelay只是初始延迟时间,而不是中间延迟时间;
  2. 也许你把它藏在别的地方了,在代码中我看不到任何问题。
- João Silva
再次感谢。我的计时器最初设置为250。现在我可以看到输出按预期每秒生成一次。然而,使用此计时器的整个目的是更新我的JFrame上的标签。正在发生的是,在计时器完成之前,最后一行myTest.hideButtons()已经执行!我使用计时器仅是为了延迟此行直到其他所有内容运行完毕。我一直在阅读有关这些计时器的文章,但显然我不理解如何正确使用它们。你能看出我需要做什么吗?再次感谢,感谢你的帮助! - AndroidDev
没关系,我解决了。我只需要将那行代码移到计时器的结尾就可以了。我没有考虑到线程的影响。感谢你们的帮助,我很感激。 - AndroidDev

5
首先,在第一次运行时停止计时器:
myTimer.stop(); <---- remove this call
myTest.hideTestButtons(false);

因此,您的计时器将不再被调用。

在解决了这个问题之后,您正在初始化

int countSeconds = 3;

每次在actionPerformed中调用,因此计数器永远不会结束。

您需要将此移动到类级别并在启动定时器之前初始化它。


谢谢!那是问题的一部分。 - AndroidDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接