多次调用startTimer方法(Java)

多次调用startTimer方法(Java),java,timer,actionlistener,Java,Timer,Actionlistener,所以我一直在浏览网页寻找答案,但感觉不知所措,似乎找不到对此的解释。对于我的一个类,我们得到了一个与我正在使用的代码非常相似的示例,我复制了它(我知道这很危险,但不知道如何进行) 我试图使它在按下按钮时,一个JLabel读取某个文本,5秒钟后该文本消失。我已经能够成功地做到这一点,但有一个陷阱。我有6个JButton共享同一个ActionListener,在适当的条件下,它可以调用startStatusTimer方法 如果一个按钮被按下,在5秒内另一个按钮被按下,它会启动另一个计时器,我按下的按

所以我一直在浏览网页寻找答案,但感觉不知所措,似乎找不到对此的解释。对于我的一个类,我们得到了一个与我正在使用的代码非常相似的示例,我复制了它(我知道这很危险,但不知道如何进行)

我试图使它在按下按钮时,一个JLabel读取某个文本,5秒钟后该文本消失。我已经能够成功地做到这一点,但有一个陷阱。我有6个JButton共享同一个ActionListener,在适当的条件下,它可以调用startStatusTimer方法

如果一个按钮被按下,在5秒内另一个按钮被按下,它会启动另一个计时器,我按下的按钮越多,我得到的计时器就越多,似乎永远不会停止。文本最终会消失,但只有在按下第一个按钮的5秒钟后才会消失

在几秒钟内多次按下按钮后,我会不断打印出大于5的计数值,但由于if语句,我看不出这是怎么回事

让一堆计时器在后台运行似乎不是一个好的编码实践,那么如何阻止它们呢

private void startStatusTimer()
{
    ActionListener taskPerformer = new ActionListener() 
    {
        int count=0;
        public void actionPerformed(ActionEvent event) 
        {
            count++;
            System.out.println(count);
            if(count>=5)
            {
                statusLabel.setText("");
                statusTimer.stop();
            }
        }
    };
    statusTimer = new Timer(second, taskPerformer);
    statusTimer.start();
}
System.out.println仅用于调试。非常感谢您的帮助

让一堆计时器在后台运行似乎不是一个好的编码实践

一般来说,不需要,如果可以的话,您不想让多个Swing
计时器运行。它们不能很好地扩展(你添加的越多,情况就越糟)。如果您尝试做相同或类似的事情,请尝试使用尽可能少的
计时器

相反,请尝试创建
计时器的单个实例

 public class ... {
     private Timer wipeOutTimer;

     public ...() {
          wipeOutTimer = new Timer(5000, new ActionListener() {
              public void actionPerformed(ActionEvent event) 
              {
                  statusLabel.setText("");
              }
          });
          wipeOutTimer.setRepeats(false);
    }
private void startStatusTimer() {
    if (!wipeOutTimer.isRunning()) {
        wipeOutTimer.start();
    }
然后在
startstatusimer
中,您可以检查
计时器的状态

 public class ... {
     private Timer wipeOutTimer;

     public ...() {
          wipeOutTimer = new Timer(5000, new ActionListener() {
              public void actionPerformed(ActionEvent event) 
              {
                  statusLabel.setText("");
              }
          });
          wipeOutTimer.setRepeats(false);
    }
private void startStatusTimer() {
    if (!wipeOutTimer.isRunning()) {
        wipeOutTimer.start();
    }
这将确保无论您按下按钮多少次,都只会有一个
计时器运行,并且在5秒内只会启动一次

那我怎么阻止他们呢

这取决于你想做什么。您可以使用
setRepeats(false)
使计时器只运行一次。您还可以使用
isRunning
检查
计时器是否已在运行,甚至可以使用
restart
在需要时重置计时器

如何使计时器在每次按下按钮时重新启动到5秒

只需调用
restart

private void startStatusTimer() {
    if (!wipeOutTimer.isRunning()) {
        wipeOutTimer.start();
    } else {
        wipeOutTimer.restart();
    }

实际上,您每次都可以调用
restart
,但这说明了一些您可能不知道的附加功能…

仅当
statusTimer
为空时创建
statusTimer
,并在逻辑完成后将其清除为
null
。也许,通过将
synchronized(someFinalObject)
添加到侦听器和
startstatusimer
最后两条语句中,使此代码线程安全也是值得的。谢谢Victor Sorokin,我添加了null语句,它确实阻止了多个计时器的关闭。。。唯一的一件事是,我希望尝试启动的最后一个计时器是5秒计时器的开始。如果按下按钮2秒钟后再次按下按钮,我希望在JLabel清除之前还有5秒钟,而不是3秒钟。感谢您的回复。我看你做的方式更简洁明了,而且它确实阻止了计时器启动。但有一件事。。。在我看来,计时器并不是每次按下按钮都会重新启动到5秒,而是从第一次按下开始持续倒数5秒。如何使计时器在每次按下按钮时重新启动到5秒?我可以尝试一下:private void startstatusimer(){if(wipeOutTimer.isRunning()){wipeOutTimer.stop();wipeOutTimer.start();}我会尝试一下……计时器设置为不重复,所以一旦到达前5秒,它就会停止。如果,您想“重置”
计时器
每次调用
startStatistimer
时,如果
正在运行
为真,只需调用
重新启动
,这将重置计时器…最后一个问题。关于我最初是如何执行的,它会继续每秒重复ActionExecuted方法,因为默认情况下会重复?setRepeat(false)将其更改为仅重复一次?抱歉,我确信这对大多数人来说似乎是超级基本的,但我对编程非常陌生。是的,
setRepeats
定义了您希望
计时器继续单击(如时钟)还是在第一次运行后停止(如秒表)