Documentation

The Java™ Tutorials
Hide TOC
Tasks that Have Interim Results具有临时结果的任务
Trail: Creating a GUI With Swing
Lesson: Concurrency in Swing
Section: Worker Threads and SwingWorker

Tasks that Have Interim Results具有中期结果的任务

It is often useful for a background task to provide interim results while it is still working. 后台任务在工作时提供临时结果通常很有用。The task can do this by invoking SwingWorker.publish. 任务可以通过调用SwingWorker.publish来完成此任务。This method accepts a variable number of arguments. 此方法接受数量可变的参数。Each argument must be of the type specified by SwingWorker's second type parameter.每个参数必须是SwingWorker的第二个类型参数指定的类型。

To collect results provided by publish, override SwingWorker.process This method will be invoked from the event dispatch thread. 要收集publish提供的结果,请重写SwingWorker.process。将从事件分派线程调用此方法。Results from multiple invocations of publish are often accumulated for a single invocation of process.多次调用SwingWorker.process的结果通常会累积为单个process调用。

Let's look at the way the Flipper.java example uses publish to provide interim results. 让我们看看Flipper.java示例使用publish提供临时结果的方式。Click the Launch button to run Flipper using Java™ Web Start (download JDK 7 or later). 单击Launch按钮,使用Java™Web启动运行Flipper(下载JDK 7或更高版本)。Or, to compile and run the example yourself, consult the example index.或者,要自己编译和运行示例,请参考示例索引

Launches the Flipper example

This program tests the fairness of java.util.Random by generating a series of random boolean values in a background task. 该程序通过在后台任务中生成一系列随机boolean值来测试java.util.Random的公平性。This is equivalent to flipping a coin; hence the name Flipper. 这相当于抛硬币;因此命名为FlipperTo report its results, the background task uses an object of type FlipPair要报告结果,后台任务使用FlipPair类型的对象

private static class FlipPair {
    private final long heads, total;
    FlipPair(long heads, long total) {
        this.heads = heads;
        this.total = total;
    }
}

The heads field is the number of times the random value has been true; the total field is the total number of random values.heads字段是随机值为真的次数;总字段是随机值的总数。

The background task is represented by an instance of FlipTask:后台任务由FlipTask的一个实例表示:

private class FlipTask extends SwingWorker<Void, FlipPair> {

Since the task does not return a final result, it does not matter what the first type parameter is; Void is used as a placeholder. 由于任务不返回最终结果,因此第一个类型参数是什么并不重要;Void用作占位符。The task invokes publish after each "coin flip":任务在每次“硬币翻转”后调用publish

@Override
protected Void doInBackground() {
    long heads = 0;
    long total = 0;
    Random random = new Random();
    while (!isCancelled()) {
        total++;
        if (random.nextBoolean()) {
            heads++;
        }
        publish(new FlipPair(heads, total));
    }
    return null;
}

(The isCancelled method is discussed in the next section.) Because publish is invoked very frequently, a lot of FlipPair values will probably be accumulated before process is invoked in the event dispatch thread; process is only interested in the last value reported each time, using it to update the GUI:(下一节将讨论isCancelled方法。)由于publish调用非常频繁,因此在事件分派线程中调用process之前,可能会积累大量FlipPair值;process只对每次报告的最后一个值感兴趣,使用它更新GUI:

protected void process(List<FlipPair> pairs) {
    FlipPair pair = pairs.get(pairs.size() - 1);
    headsText.setText(String.format("%d", pair.heads));
    totalText.setText(String.format("%d", pair.total));
    devText.setText(String.format("%.10g", 
            ((double) pair.heads)/((double) pair.total) - 0.5));
}

If Random is fair, the value displayed in devText should get closer and closer to 0 as Flipper runs.如果Random是公平的,那么随着Flipper的运行,devText中显示的值应该越来越接近0。


Note: The setText method used in Flipper is actually "thread safe" as defined in its specification. Flipper中使用的setText方法实际上是其规范文档中定义的“线程安全”方法。That means that we could dispense with publish and process and set the text fields directly from the worker thread. 这意味着我们可以放弃publishprocess,直接从工作线程设置文本字段。We've chosen to ignore this fact in order to provide a simple demonstration of SwingWorker interim results. 为了提供SwingWorker临时结果的简单演示,我们选择忽略这一事实。

Previous page: Simple Background Tasks
Next page: Canceling Background Tasks