- java.lang.Object
-
- javax.swing.SwingWorker<T,V>
-
- 参数类型
-
T
- 此SwingWorker's
doInBackground
和get
方法返回的结果类型 -
V
- 此SwingWorker's
publish
和process
方法用于执行中间结果的类型
- 实现的所有接口
-
Runnable
,Future<T>
,RunnableFuture<T>
public abstract class SwingWorker<T,V> extends Object implements RunnableFuture<T>
一个抽象类,用于在后台线程中执行冗长的GUI交互任务。 可以使用几个后台线程来执行此类任务。 但是,为任何特定的SwingWorker
选择线程的确切策略是未指定的,不应该依赖。使用Swing编写多线程应用程序时,请记住以下两个约束:(有关详细信息,请参阅Concurrency in Swing ):
- 不应在Event Dispatch Thread上运行耗时的任务。 否则应用程序将无响应。
- 应仅在Event Dispatch Thread上访问Swing组件。
这些约束意味着具有时间密集型计算的GUI应用程序需要至少两个线程:1)执行冗长任务的线程和2)所有GUI相关活动的事件调度线程 (EDT)。 这涉及线程间通信,这可能很难实现。
SwingWorker
适用于需要在后台线程中运行长时间运行任务并在完成或处理时为UI提供更新的情况。 子类SwingWorker
必须实现doInBackground()
方法才能执行后台计算。工作流程
SwingWorker
的生命周期涉及三个线程:当前线程:在此线程上调用
execute()
方法。 它为工作线程执行计划SwingWorker
并立即返回。 可以使用get
方法等待SwingWorker
完成。工作线程:在此线程上调用
doInBackground()
方法。 这是所有背景活动应该发生的地方。 要通知PropertyChangeListeners
有关绑定属性更改,请使用firePropertyChange
和getPropertyChangeSupport()
方法。 默认情况下,有两个绑定属性可用:state
和progress
。事件调度线程 :此线程上发生所有与Swing相关的活动。
SwingWorker
调用process
和done()
方法并通知此线程上的任何PropertyChangeListeners
。
通常, Current线程是Event Dispatch Thread 。
在工作线程上调用
doInBackground
方法之前,SwingWorker
通知任何PropertyChangeListeners
state
属性更改为StateValue.STARTED
。doInBackground
方法完成后,执行done
方法。 然后SwingWorker
通知任何PropertyChangeListeners
state
属性更改为StateValue.DONE
。SwingWorker
仅设计为执行一次。SwingWorker
执行SwingWorker
不会导致两次调用doInBackground
方法。样品使用
以下示例说明了最简单的用例。 某些处理在后台完成,完成后更新Swing组件。
假设我们想要找到“生命的意义”并将结果显示在
JLabel
。final JLabel label; class MeaningOfLifeFinder extends SwingWorker<String, Object> {
@Override
public String doInBackground() { return findTheMeaningOfLife(); }@Override
protected void done() { try { label.setText(get()); } catch (Exception ignore) { } } } (new MeaningOfLifeFinder()).execute();下一个示例在您希望在Event Dispatch Thread上准备好处理数据的情况下非常有用。
现在我们想要找到前N个素数并在
JTextArea
显示结果。 虽然这是计算,但我们希望在JProgressBar
更新我们的进度。 最后,我们还想将素数打印到System.out
。class PrimeNumbersTask extends SwingWorker<List<Integer>, Integer> { PrimeNumbersTask(JTextArea textArea, int numbersToFind) { //initialize }
@Override
public List<Integer> doInBackground() { while (! enough && ! isCancelled()) { number = nextPrimeNumber(); publish(number); setProgress(100 * numbers.size() / numbersToFind); } } return numbers; }@Override
protected void process(List<Integer> chunks) { for (int number : chunks) { textArea.append(number + "\n"); } } } JTextArea textArea = new JTextArea(); final JProgressBar progressBar = new JProgressBar(0, 100); PrimeNumbersTask task = new PrimeNumbersTask(textArea, N); task.addPropertyChangeListener( new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { if ("progress".equals(evt.getPropertyName())) { progressBar.setValue((Integer)evt.getNewValue()); } } }); task.execute(); System.out.println(task.get()); //prints all prime numbers we have got因为
SwingWorker
实现了Runnable
,SwingWorker
可以将SwingWorker
提交到Executor
以供执行。- 从以下版本开始:
- 1.6
-
-
嵌套类汇总
嵌套类 变量和类型 类 描述 static class
SwingWorker.StateValue
state
绑定属性的值。
-
构造方法摘要
构造方法 构造器 描述 SwingWorker()
构造此SwingWorker
。
-
方法摘要
所有方法 实例方法 抽象方法 具体的方法 变量和类型 方法 描述 void
addPropertyChangeListener(PropertyChangeListener listener)
将PropertyChangeListener
添加到侦听器列表。protected abstract T
doInBackground()
计算结果,如果无法执行,则抛出异常。protected void
done()
在doInBackground
方法完成后在 事件调度线程上执行。void
execute()
安排此SwingWorker
在 工作线程上执行。void
firePropertyChange(String propertyName, Object oldValue, Object newValue)
向任何已注册的侦听器报告绑定属性更新。T
get()
如果需要等待计算完成,然后检索其结果。T
get(long timeout, TimeUnit unit)
如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。int
getProgress()
返回progress
绑定属性。PropertyChangeSupport
getPropertyChangeSupport()
返回PropertyChangeSupport
的SwingWorker
。SwingWorker.StateValue
getState()
返回SwingWorker
状态绑定属性。protected void
process(List<V> chunks)
在 事件调度线程上异步接收来自publish
方法的数据块。protected void
publish(V... chunks)
将数据块发送到process(java.util.List<V>)
方法。void
removePropertyChangeListener(PropertyChangeListener listener)
从侦听器列表中删除PropertyChangeListener
。void
run()
将此Future
设置为计算结果,除非它已被取消。protected void
setProgress(int progress)
设置progress
绑定属性。-
声明方法的类 java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
声明方法的接口 java.util.concurrent.Future
cancel, isCancelled, isDone
-
-
-
-
方法详细信息
-
doInBackground
protected abstract T doInBackground() throws 异常
计算结果,如果无法执行,则抛出异常。请注意,此方法仅执行一次。
注意:此方法在后台线程中执行。
- 结果
- 计算结果
- 异常
-
异常
- 如果无法计算结果
-
run
public final void run()
将此Future
设置为计算结果,除非它已被取消。- Specified by:
-
run
在界面Runnable
- Specified by:
-
run
在界面RunnableFuture<T>
- 另请参见:
-
Thread.run()
-
publish
@SafeVarargs protected final void publish(V... chunks)
将数据块发送到process(java.util.List<V>)
方法。 此方法是从里面使用doInBackground
方法在里面的事件指派线程提供用于处理中间结果process
方法。因为
process
方法是异步调用的事件指派线程多次调用到publish
方法之前,可能会出现process
执行方法。 出于性能目的,所有这些调用都合并为一个带有连接参数的调用。例如:
publish("1"); publish("2", "3"); publish("4", "5", "6");
可能导致:process("1", "2", "3", "4", "5", "6")
样品使用 。 此代码段加载一些表格数据并使用它更新
DefaultTableModel
。 请注意,可以安全地从process
方法中改变tableModel,因为它是在Event Dispatch Thread上调用的。class TableSwingWorker extends SwingWorker<DefaultTableModel, Object[]> { private final DefaultTableModel tableModel; public TableSwingWorker(DefaultTableModel tableModel) { this.tableModel = tableModel; }
@Override
protected DefaultTableModel doInBackground() throws Exception { for (Object[] row = loadData(); ! isCancelled() && row != null; row = loadData()) { publish((Object[]) row); } return tableModel; }@Override
protected void process(List<Object[]> chunks) { for (Object[] row : chunks) { tableModel.addRow(row); } } }- 参数
-
chunks
- 要处理的中间结果 - 另请参见:
-
process(java.util.List<V>)
-
process
protected void process(List<V> chunks)
在事件调度线程上异步接收来自publish
方法的数据块。有关更多详细信息,请参阅
publish(V...)
方法。- 参数
-
chunks
- 要处理的中间结果 - 另请参见:
-
publish(V...)
-
done
protected void done()
在doInBackground
方法完成后在事件调度线程上执行。 默认实现什么都不做。 子类可以重写此方法以对Event Dispatch Thread执行完成操作。 请注意,您可以在此方法的实现中查询状态,以确定此任务的结果或此任务是否已取消。- 另请参见:
-
doInBackground()
,Future.isCancelled()
,get()
-
setProgress
protected final void setProgress(int progress)
设置progress
绑定属性。 该值应为0到100。由于
PropertyChangeListener
s的在事件指派线程多次调用异步通知setProgress
方法可能发生前的任何PropertyChangeListeners
被调用。 出于性能目的,所有这些调用仅与最后一个调用参数合并为一个调用。例如,以下调用:
setProgress(1); setProgress(2); setProgress(3);
可能会导致单个PropertyChangeListener
通知,其值为3
。- 参数
-
progress
- 要设置的进度值 - 异常
-
IllegalArgumentException
- 值不是0到100
-
getProgress
public final int getProgress()
返回progress
绑定属性。- 结果
- 进度约束属性。
-
execute
public final void execute()
安排此SwingWorker
在工作线程上执行。 有许多工作线程可用。 如果所有工作线程都忙于处理其他SwingWorkers
此SwingWorker
被置于等待队列中。注意:
SwingWorker
仅设计为执行一次。SwingWorker
执行SwingWorker
不会导致两次调用doInBackground
方法。
-
get
public final T get() throws InterruptedException, ExecutionException
如果需要等待计算完成,然后检索其结果。注意:在事件调度线程上调用
get
阻止所有事件(包括重新绘制)被处理,直到此SwingWorker
完成。如果希望
SwingWorker
阻止事件调度线程,我们建议您使用模式对话框 。例如:
class SwingWorkerCompletionWaiter implements PropertyChangeListener { private JDialog dialog; public SwingWorkerCompletionWaiter(JDialog dialog) { this.dialog = dialog; } public void propertyChange(PropertyChangeEvent event) { if ("state".equals(event.getPropertyName()) && SwingWorker.StateValue.DONE == event.getNewValue()) { dialog.setVisible(false); dialog.dispose(); } } } JDialog dialog = new JDialog(owner, true); swingWorker.addPropertyChangeListener( new SwingWorkerCompletionWaiter(dialog)); swingWorker.execute(); //the dialog will be visible until the SwingWorker is done dialog.setVisible(true);
- Specified by:
-
get
接口Future<T>
- 结果
- 计算结果
- 异常
-
CancellationException
- 如果计算被取消 -
InterruptedException
- 如果当前线程在等待时被中断 -
ExecutionException
- 如果计算引发异常
-
get
public final T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
如果需要,最多等待计算完成的给定时间,然后检索其结果(如果可用)。有关详细信息,请参阅
get()
。- Specified by:
-
get
在界面Future<T>
- 参数
-
timeout
- 等待的最长时间 -
unit
- 超时参数的时间单位 - 结果
- 计算结果
- 异常
-
CancellationException
- 如果计算被取消 -
InterruptedException
- 如果当前线程在等待时被中断 -
ExecutionException
- 如果计算引发异常 -
TimeoutException
- 如果等待超时
-
addPropertyChangeListener
public final void addPropertyChangeListener(PropertyChangeListener listener)
将PropertyChangeListener
添加到侦听器列表中。 监听器已注册所有属性。 可以多次添加相同的侦听器对象,并且在添加时将多次调用它。 如果listener
是null
,则不会抛出任何异常并且不执行任何操作。注意:这只是一个方便的包装器。 所有工作
PropertyChangeSupport
getPropertyChangeSupport()
委托给PropertyChangeSupport 。- 参数
-
listener
- 要添加的PropertyChangeListener
-
removePropertyChangeListener
public final void removePropertyChangeListener(PropertyChangeListener listener)
从侦听器列表中删除PropertyChangeListener
。 这将删除为所有属性注册的PropertyChangeListener
。 如果listener
将listener
添加到同一事件源,则会在删除后将其通知一次。 如果listener
是null
,或者从未添加过,则不会抛出任何异常并且不执行任何操作。注意:这只是一个方便的包装器。 所有工作
PropertyChangeSupport
getPropertyChangeSupport()
委托给PropertyChangeSupport 。- 参数
-
listener
- 要删除的PropertyChangeListener
-
firePropertyChange
public final void firePropertyChange(String propertyName, Object oldValue, Object newValue)
向任何已注册的侦听器报告绑定属性更新。 如果old
和new
相等且非空,则old
触发任何事件。此
SwingWorker
将是任何生成的事件的源。如果取消了事件指派线程
PropertyChangeListeners
都在事件指派线程上异步地通知。注意:这只是一个方便的包装器。 所有工作
PropertyChangeSupport
getPropertyChangeSupport()
委托给PropertyChangeSupport 。- 参数
-
propertyName
- 已更改的属性的编程名称 -
oldValue
- 属性的旧值 -
newValue
- 该属性的新值
-
getPropertyChangeSupport
public final PropertyChangeSupport getPropertyChangeSupport()
返回PropertyChangeSupport
的SwingWorker
。 当需要灵活访问绑定属性支持时,使用此方法。此
SwingWorker
将成为任何生成事件的源。注:返回
PropertyChangeSupport
通知任何PropertyChangeListener
小号异步对事件的事件调度线程firePropertyChange
或fireIndexedPropertyChange
被叫停事件指派线程 。- 结果
-
PropertyChangeSupport
这个SwingWorker
-
getState
public final SwingWorker.StateValue getState()
返回SwingWorker
状态绑定属性。- 结果
- 目前的状态
-
-