在计时器滴答一秒后,如何在java中更改标签文本?

时间:2014-10-23 08:14:24

标签: java swing timer jlabel

我有一个延迟5秒的计时器。我试图在第二次传递后更改名为lblTimer的标签作为倒计时。我遇到了问题,因为它目前仅在5秒内工作。你有什么建议吗?

protected void Addition() {
    //addition function 

    final int delay = 5000; //milliseconds

    ActionListener taskPerformer = new ActionListener() {
        @SuppressWarnings("unused")
        public void actionPerformed(ActionEvent evt) {
            //...Perform a task...
            frame.getContentPane().setBackground(Color.red);
        }
    };

    new Timer(delay, taskPerformer).start();
    Random RandomNumber = new Random();
    int number1 = RandomNumber.nextInt(12);
    int number2 = RandomNumber.nextInt(12);
    int number3 = RandomNumber.nextInt(12);
    lblAnswer.setText("");
    lblFirstNumber.setText(""+ number1);
    lblfunction1.setText("+");
    lblsecondNumber.setText(""+number2);
    lblfunction2.setText("+");
    lblthirdnumber.setText(""+number3);
    lblequals.setText("=");
    answer = number1+number2+number3;
    if(delay <= 1000){
        lblTimer.setText("1"); 
    }    
    else if(delay == 2000){
        lblTimer.setText("2"); 
    }    
    else if(delay == 3000){
        lblTimer.setText("3"); 
    } 
    else if(delay == 4000){
        lblTimer.setText("4"); 
    }    
    else if (delay == 5000){
        lblTimer.setText("5"); 
    }
}

3 个答案:

答案 0 :(得分:3)

你的问题的答案,我认为是“为什么这不起作用?”,是你在任何时候都没有重新检查经过的时间。变量延迟始终设置为5000,并且永远不会更新。

愚蠢的解决方案:

lblTimer.setText("5");
Thread.sleep(1000)
lblTimer.setText("4");
Thread.sleep(1000)
lblTimer.setText("3");
Thread.sleep(1000)
lblTimer.setText("2");
Thread.sleep(1000)
lblTimer.setText("1");
Thread.sleep(1000)
lblTimer.setText("0");

除非你需要满足你生病的恋物癖,否则不要这样做。

四线

与上述相同。不要这样做。

for (int i = secondsToWait; i >= 0; i--) {
    lblTimer.setText(i + "");
    Thread.sleep(1000);
}

可接受的解决方案:

使用Timer安排在给定时间段后执行的任务。您可以使用计时器以给定的间隔多次触发相同的任务。

    Timer timer = new Timer();

    int secondsToWait = 5;
    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            secondsToWait--;
            lblTimer.setText(secondsToWait + "");
            if (secondsToWait == 0) {
                timer.cancel();
                timer.purge();
            }
        }
    };

    lblTimer.setText(secondsToWait + "");
    timer.scheduleAtFixedRate(task, 1000, 1000);

最佳解决方案:

使用ScheduledExecutorService代替计时器。这是更好的,因为ScheduledExecutorService使用线程而不是Timer。谷歌吧。

    ScheduledExecutorService exec = Executors.newScheduledThreadPool(1);

    int secondsToWait = 5;
    Runnable task = new Runnable() {
        @Override
        public void run() {
            secondsToWait--;
            lblTimer.setText(secondsToWait + "");
            if (secondsToWait == 0) {
                exec.shutdown();
            }
        }
    };

    lblTimer.setText(secondsToWait + "");
    exec.scheduleAtFixedRate(task, 1, 1, TimeUnit.SECONDS);

编辑:正如Stefan指出的那样,对于摆动GUI应用程序,摆动Timer将是最佳选择。

答案 1 :(得分:0)

看起来应该是这样的:

1)创建计时器

2)创建TimerTask并实现run方法(更新计数变量并检查计数器是否为零。如果为零,则停止计时器)

3)安排任务每秒运行

int count = [INITVALUE];

...

public void startMethod() {
    final Timer timer = new Timer();
    timer.shedule(new TimerTask() {
          @Override
          public void run() {
             count--;
             lblTimer.setText(count+"");
             if (count == 0) {
               timer.cancel();
               timer.purge();
             }
          }
    },1000);

}

答案 2 :(得分:0)

竖起大拇指@Olavi Mustanoja你的回答显示了我以前从未尝试过的选项。 正如他最后在编辑时建议的那样,如果您使用GUI,javax.swing.Timer非常方便。

import javax.swing.Timer;

private int secondsToWait = 5000; //Time in milliseconds
private Timer timer;

....

//The following section should be inside a method member
timer = new Timer(secondsToWait, e -> {
        if(secondsToWait == 0)
            timer.stop();//Stop if secondsToWait is already zero
        lblTimer.setText((secondsToWait/1000) + ""); //Update the label with the current sec
        timer.setDelay(secondsToWait);
        secondsToWait -= 1000; //Reduce time by 1sec each time
    });
    timer.start();

...