如何使用摇摆计时器

Swing 计时器(javax.swing.Timer的实例)在指定的延迟后触发一个或多个动作事件。不要将 Swing 计时器与java.util软件包中的通用计时器功能混淆。此页面仅描述 Swing 计时器。

通常,我们建议对与 GUI 有关的任务使用 Swing 计时器,而不要使用通用计时器,因为 Swing 计时器都共享相同的,预先存在的计时器线程,并且与 GUI 相关的任务会在事件调度线程上自动执行。但是,如果您不打算通过计时器触摸 GUI,或者需要执行冗 Long 的处理,则可以使用通用计时器。

您可以通过两种方式使用 Swing 计时器:

  • 延迟一次,一次执行一次任务。
    例如,工具提示 管理 器使用 Swing 计时器来确定何时显示工具提示以及何时隐藏工具提示。

  • 重复执行任务。
    例如,您可以执行动画或更新显示目标进度的组件。

摆动计时器非常易于使用。创建计时器时,您可以指定一个动作侦听器,以在计时器“关闭”时收到通知。此侦听器中的actionPerformed方法应包含您需要执行的任何任务的代码。创建计时器时,您还可以指定计时器触发之间的毫秒数。如果您希望计时器仅关闭一次,则可以在计时器上调用setRepeats(false)。要启动计时器,请调用其start方法。要暂停它,请调用stop

请注意,Swing 计时器的任务是在事件分发线程中执行的。这意味着任务可以安全地操作组件,但是也意味着任务应该快速执行。如果任务可能需要一段时间才能执行,请考虑使用SwingWorker代替计时器或在计时器之外使用。有关使用SwingWorker类的说明以及有关在多线程程序中使用 Swing 组件的信息,请参见Swing 中的并发

让我们看一个使用计时器定期更新组件的示例。 TumbleItemServlets 使用计时器定期更新其显示。 (要查看此 Servlets 正在运行,请转到如何制作 Servlets。此 Servlets 首先创建并启动计时器:

timer = new Timer(speed, this);
timer.setInitialDelay(pause);
timer.start();

speedpause变量表示 applet 参数;按照另一页上的配置,它们分别是 100 和 1900,因此第一次计时器事件将在大约 1.9 秒内发生,并每隔 0.1 秒重复发生一次。通过将this指定为Timer构造函数的第二个参数,TumbleItem可以指定它是计时器事件的动作侦听器。

启动计时器后,TumbleItem开始在后台线程中加载一系列图像。同时,计时器事件开始发生,导致actionPerformed方法执行:

public void actionPerformed(ActionEvent e) {
    //If still loading, can't animate.
    if (!worker.isDone()) {
        return;
    }

    loopslot++;

    if (loopslot >= nimgs) {
        loopslot = 0;
        off += offset;

        if (off < 0) {
            off = width - maxWidth;
        } else if (off + maxWidth > width) {
            off = 0;
        }
    }

    animator.repaint();

    if (loopslot == nimgs - 1) {
        timer.restart();
    }
}

在加载图像之前,worker.isDone返回false,因此有效地忽略了计时器事件。事件处理代码的第一部分只是设置动画控件的paintComponent方法中使用的值:loopslot(动画中下一个图形的索引)和off(下一个图形的水平offset)。

final,loopslot将到达图像数组的末尾并重新开始。发生这种情况时,actionPerformed末尾的代码将重新启动计时器。这样做会导致动画序列再次开始之前的短暂延迟。