|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
java.lang.Object javax.swing.SwingWorker<T,V>
T
- この SwingWorker
の doInBackground
メソッドおよび get
メソッドによって返される結果の型V
- この SwingWorker
の publish
メソッド および process
メソッドを使って中間結果を計算するために使用する型public abstract class SwingWorker<T,V>
GUI とやりとりする時間のかかるタスクを、専用のスレッドで実行するための abstract クラスです。
Swing を使ってマルチスレッドアプリケーションを記述する場合は、次の 2 つの制約に注意してください (詳細は「How to Use Threads」を参照)。
これらの制約があるため、時間のかかる GUI アプリケーションには、1) 時間のかかるタスクを実行するスレッドと、2) GUI 関連のすべての作業を実行するイベントディスパッチスレッド (EDT) の少なくとも 2 つのスレッドが必要になります。このように複数のスレッドを使用する場合はスレッド間通信を行う必要がありますが、この機能は簡単に実装できない場合があります。
SwingWorker
は、バックグラウンドスレッドで実行時間の長いタスクを実行する必要があり、その実行中または実行完了後に UI を更新する必要がある場合を想定して設計されています。SwingWorker
のサブクラスは、バックグラウンドで計算を行うため、doInBackground()
メソッドを実装する必要があります。
ワークフロー
SwingWorker
のライフサイクル内には、次の 3 つのスレッドが存在します。
現在のスレッド:execute()
メソッドはこのスレッド上で呼び出されます。このメソッドは、ワークスレッドでの SwingWorker
の実行スケジュールを立て、その情報をただちに返します。get
メソッドを使って SwingWorker
の完了を待機することもできます。
ワークスレッド:doInBackground()
メソッドはこのスレッド上で呼び出されます。ここで、すべてのバックグラウンド作業が発生します。PropertyChangeListeners
にバウンドプロパティーの変更を通知するには、firePropertyChange
メソッドと getPropertyChangeSupport()
メソッドを使用します。デフォルトでは、state
と progress
の 2 つのバウンドプロパティーを使用できます。
イベントディスパッチスレッド:Swing 関連のすべての作業は、このスレッド上で発生します。SwingWorker
は process
メソッドと done()
メソッドを呼び出し、このスレッド上のすべての PropertyChangeListeners
に通知します。
現在のスレッドがイベントディスパッチスレッドである場合もあります。
ワークスレッド上で doInBackground
メソッドが呼び出される前に、SwingWorker
はすべての PropertyChangeListeners
に、state
プロパティーの値が StateValue.STARTED
に変更されたことを通知します。doInBackground
メソッドの実行が完了すると、done
メソッドが実行されます。続いて、SwingWorker
はすべての PropertyChangeListeners
に、state
プロパティーの値が StateValue.DONE
に変更されたことを通知します。
SwingWorker
は 1 回だけ実行されるように設計されています。SwingWorker
を複数回実行しても、doInBackground
メソッドは 1 回しか呼び出されません。
使用例
次に、もっとも単純な使用例を示します。一部の処理はバックグラウンドで実行されます。実行が完了したら、Swing コンポーネントを更新します。
ここでは、「Meaning of Life」を検索し、結果を 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();
次の例は、準備の完了したデータをイベントディスパッチスレッド上で処理する場合に使用できます。
ここでは、最初の 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
を Executor
に送信して、実行することができます。
入れ子のクラスの概要 | |
---|---|
static class |
SwingWorker.StateValue
state バウンドプロパティーの値です。 |
コンストラクタの概要 | |
---|---|
SwingWorker()
この SwingWorker を構築します。 |
メソッドの概要 | |
---|---|
void |
addPropertyChangeListener(PropertyChangeListener listener)
PropertyChangeListener をリスナーリストに追加します。 |
boolean |
cancel(boolean mayInterruptIfRunning)
このタスクの実行の取り消しを試みます。 |
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()
この SwingWorker の PropertyChangeSupport を返します。 |
SwingWorker.StateValue |
getState()
SwingWorker 状態バウンドプロパティーを返します。 |
boolean |
isCancelled()
このタスクが正常に完了する前に取り消された場合は true を返します。 |
boolean |
isDone()
このタスクが完了した場合は true を返します。 |
protected void |
process(List<V> chunks)
イベントディスパッチスレッド上で、 publish メソッドから非同期でデータチャンクを受信します。 |
protected void |
publish(V... chunks)
process(java.util.List メソッドにデータチャンクを送信します。 |
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 |
コンストラクタの詳細 |
---|
public SwingWorker()
SwingWorker
を構築します。
メソッドの詳細 |
---|
protected abstract T doInBackground() throws Exception
このメソッドは 1 回だけ実行されます。
注:このメソッドは、バックグラウンドスレッドで実行されます。
Exception
- 結果を計算できなかった場合public final void run()
Future
に計算結果を設定します。
Runnable
内の run
RunnableFuture<T>
内の run
Thread.run()
protected final void publish(V... chunks)
process(java.util.List)
メソッドにデータチャンクを送信します。このメソッドは doInBackground
メソッド内部で使用され、イベントディスパッチスレッド上での処理のため process
メソッド内部で中間結果を配信します。
process
メソッドはイベントディスパッチスレッド上で非同期で呼び出されるので、process
メソッドが実行される前に、publish
メソッドが複数回呼び出されることがあります。パフォーマンスの向上のため、これらのすべての呼び出しは 1 回の呼び出しにまとめられます。各呼び出しの引数は連結されます。
例を示します。
publish("1"); publish("2", "3"); publish("4", "5", "6");結果は次のようになります。
process("1", "2", "3", "4", "5", "6")
使用例。このコード (抜粋) は、テーブルデータをロードし、このテーブルデータを使って DefaultTableModel
を更新します。これはイベントディスパッチスレッド上で呼び出されるので、process
メソッド内部で tableModel が変更される危険性はありません。
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)
protected void process(List<V> chunks)
publish
メソッドから非同期でデータチャンクを受信します。
詳細については、publish(V...)
メソッドを参照してください。
chunks
- 処理対象となる中間結果publish(V...)
protected void done()
doInBackground
メソッドの実行完了後、イベントディスパッチスレッド上で実行されます。デフォルト実装は何も実行しません。サブクラスは、このメソッドをオーバーライドして、イベントディスパッチスレッド上で完了処理を実行することがあります。このメソッドの実装内部でステータスを照会して、このタスクの結果や、このタスクが取り消されていないかどうかを確認することができます。
doInBackground()
,
isCancelled()
,
get()
protected final void setProgress(int progress)
progress
バウンドプロパティーを設定します。0 〜 100 の値を指定するようにしてください。
PropertyChangeListener
メソッドはイベントディスパッチスレッド上で非同期で通知を受け取るので、PropertyChangeListeners
が呼び出される前に、setProgress
メソッドが複数回呼び出されることがあります。パフォーマンスの向上のため、これらのすべての呼び出しは 1 回の呼び出しにまとめられます。この場合、最後の呼び出しの引数だけが有効になります。
たとえば、次の呼び出しがあるとします。
setProgress(1); setProgress(2); setProgress(3);これは、値
3
を持つ 1 回の PropertyChangeListener
通知にまとめられます。
progress
- 設定する進捗値
IllegalArgumentException
- 0 〜 100 以外の値を指定した場合public final int getProgress()
progress
バウンドプロパティーを返します。
public final void execute()
SwingWorker
の実行スケジュールを立てます。多数のワークスレッドを使用できます。すべてのワークスレッドがほかの SwingWorkers
の処理でビジー状態になっている場合、この SwingWorker
は待機キューに入ります。
注:SwingWorker
は 1 回だけ実行されるように設計されています。SwingWorker
を複数回実行しても、doInBackground
メソッドは 1 回しか呼び出されません。
public final boolean cancel(boolean mayInterruptIfRunning)
このメソッドが復帰したあと、以降の Future.isDone()
の呼び出しでは常に true が返されます。このメソッドが true を返した場合、以降の Future.isCancelled()
の呼び出しでは常に true が返されます。
Future<T>
内の cancel
mayInterruptIfRunning
- このタスクを実行しているスレッドに割り込む必要がある場合は true、そうでない場合は、実行中のタスクを完了できる
public final boolean isCancelled()
Future<T>
内の isCancelled
public final boolean isDone()
Future<T>
内の isDone
public final T get() throws InterruptedException, ExecutionException
注:イベントディスパッチスレッド上で get
を呼び出すと、この SwingWorker
の実行が完了するまで、すべてのイベント (再ペイントなど) の処理がブロックされます。
イベントディスパッチスレッド上で SwingWorker
をブロックするには、モーダルダイアログを使用することをお勧めします。
例を示します。
class SwingWorkerCompletionWaiter extends 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);
Future<T>
内の get
InterruptedException
- 待機中に現在のスレッドで割り込みが発生した場合
ExecutionException
- 計算で例外がスローされた場合public final T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException
詳細については、get()
メソッドを参照してください。
Future<T>
内の get
timeout
- 待機する最長時間unit
- timeout 引数の時間単位
InterruptedException
- 待機中に現在のスレッドで割り込みが発生した場合
ExecutionException
- 計算で例外がスローされた場合
TimeoutException
- 待機がタイムアウトになった場合public final void addPropertyChangeListener(PropertyChangeListener listener)
PropertyChangeListener
をリスナーリストに追加します。リスナーは、すべてのプロパティーに対して登録されます。同じリスナーオブジェクトを複数回追加でき、追加した回数だけリスナーオブジェクトが呼び出されます。listener
が null
の場合、例外はスローされず、何も行われません。
注:これは簡易ラッパーです。すべての処理は、getPropertyChangeSupport()
から PropertyChangeSupport
に委譲されます。
listener
- 追加される PropertyChangeListener
public final void removePropertyChangeListener(PropertyChangeListener listener)
PropertyChangeListener
をリスナーリストから削除します。すべてのプロパティーの登録済みの PropertyChangeListener
を削除します。listener
を同じイベントソースに複数回追加している場合は、このリスナーを削除したあと通知を受信します。listener
が null
の場合、または追加されていない場合、例外はスローされず、何も行われません。
注:これは簡易ラッパーです。すべての処理は、getPropertyChangeSupport()
から PropertyChangeSupport
に委譲されます。
listener
- 削除される PropertyChangeListener
public final void firePropertyChange(String propertyName, Object oldValue, Object newValue)
old
値と new
値が等しく、null でない場合、イベントはトリガーされません。
この SwingWorker
は、生成されるすべてのイベントのソースになります。
イベントディスパッチスレッドを取り消した場合、PropertyChangeListener
はイベントディスパッチ上で非同期で通知を受信します。
注:これは簡易ラッパーです。すべての処理は、getPropertyChangeSupport()
から PropertyChangeSupport
に委譲されます。
propertyName
- 変更されたプロパティーのプログラム名oldValue
- プロパティーの変更前の値newValue
- プロパティーの変更後の値public final PropertyChangeSupport getPropertyChangeSupport()
SwingWorker
の PropertyChangeSupport
を返します。このメソッドは、バウンドプロパティーに頻繁にアクセスする必要がある場合に使用します。
この SwingWorker
は、生成されるすべてのイベントのソースになります。
注:firePropertyChange
または fireIndexedPropertyChange
がイベントディスパッチスレッドを取り消した場合、返される PropertyChangeSupport
は、イベントディスパッチスレッド上のすべての PropertyChangeListener
に非同期で通知を送信します。
SwingWorker
の PropertyChangeSupport
public final SwingWorker.StateValue getState()
SwingWorker
状態バウンドプロパティーを返します。
|
JavaTM Platform Standard Ed. 6 |
|||||||||
前のクラス 次のクラス | フレームあり フレームなし | |||||||||
概要: 入れ子 | フィールド | コンストラクタ | メソッド | 詳細: フィールド | コンストラクタ | メソッド |
Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. Documentation Redistribution Policy も参照してください。