文档

Java™ 教程
隐藏目录
如何使用Swing计时器
路径: 使用Swing创建GUI
课程: 使用其他Swing功能

如何使用Swing计时器

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

一般而言,我们建议在GUI相关任务中使用Swing计时器而不是通用计时器,因为Swing计时器共享同一个预先存在的计时器线程,并且GUI相关任务会自动在事件分派线程上执行。但是,如果您不打算从计时器中操作GUI,或者需要执行长时间处理任务,可以使用通用计时器。

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

使用Swing计时器非常简单。创建计时器时,您需要指定一个操作监听器,在计时器"触发"时通知该监听器。该监听器中的actionPerformed方法应包含您需要执行的任务的代码。创建计时器时,您还需要指定计时器触发之间的毫秒数。如果您只希望计时器触发一次,可以在计时器上调用setRepeats(false)。要启动计时器,请调用其start方法。要暂停计时器,请调用stop

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

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

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 (!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(下一个图形的水平偏移量)。

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


上一页: 如何使用操作
下一页: 如何支持辅助技术