如何在Java中正确处理定时器?

3

我希望我的计时器在5秒后只执行一次actionPerformed方法,但是它在控制台中写了很多次"Hello":

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class X{
    public static void main(String args[]) {

        ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent actionEvent) {
                System.out.println( "Hello" );
            }
        };
        Timer timer = new Timer( 5000, actionListener );
        timer.start();
    }
}

我该如何实现我想要的效果?谢谢。


1
“lots of times” 是什么意思?代码乍一看看起来没问题… - Petar Minchev
我是说它会永远输出 "Hello"。 - Rama
只打印一次“Hello”。 - Rama
5个回答

5

如前所述,最好使用 java.util.Timer,但您也可以在启动之前使用setRepeats():

timer.setRepeats(false);

2

不要忽视使用事件调度线程。使用java.util.Timer没有什么问题,但是在Swing中,javax.swing.Timer有几个优点。

import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Timer;

public class X {

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                ActionListener actionListener = new ActionListener() {

                    public void actionPerformed(ActionEvent actionEvent) {
                        System.out.println("Hello");
                    }
                };
                Timer timer = new Timer(5000, actionListener);
                timer.start();
            }
        });
    }
}

如果使用java.util.Timer,请使用continuation来更新GUI界面。

好问题,但我认为这个踩票是不合理的。如果没有在事件分派线程上发布一个Runnable,初始线程可能会在javax.swing.Timer触发之前退出,就像在我的平台上一样。 - trashgod

1
听起来你想要一个java.util.Timer而不是javax.swing.Timer

当我导入javax.util.Timer时,Java不允许我调用:java.util.Timer timer = new java.util.Timer(5000, actionListener); 它会显示“构造函数Timer(int,ActionListener)未定义”。我该如何使用Java.util实现相同的效果? - Rama
2
@Rama 不要使用java.util.Timer来处理Swing GUI相关的事件,因为与java.util.Timer相比,javax.swing.Timer不够精确,但它是处理基于Swing的Java GUI的最佳方式。 - mKorbel
1
如果使用 javax.util.Timer,请使用continuation来更新GUI。 - trashgod
是的,正如@trashgod所说,如果您需要更新GUI,请确保执行此操作的代码正在事件分派线程上运行。但是,在您的示例中,您没有运行任何与GUI交互的代码。 - Mike Tunnicliffe

1
class MyTask extends TimerTask {
    public void run() {
      System.out.println("Hello");

    }
  }

然后

timer = new Timer();
timer.schedule(new MyTask(), 5000);

我喜欢这个解决方案,但我的X类需要是可运行的,所以我实现了run来执行其他任务... - Rama

0

这应该就行了!

new JFrame().setVisible(true);

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