Swing/TwoProgressBars の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/TwoProgressBars へ行く。
- Swing/TwoProgressBars の差分を削除
--- category: swing folder: TwoProgressBars title: SwingWorkerで複数のJProgressBarを使用する tags: [SwingWorker, JProgressBar, Enum, PropertyChangeListener] author: aterai pubdate: 2011-06-13T13:44:00+09:00 description: ひとつのSwingWorkerで、進捗を表示するJProgressBarをふたつ使用します。 image: https://lh6.googleusercontent.com/-S6ko35_DIi8/TfWPa08dHvI/AAAAAAAAA9I/MNhC-0LF8YQ/s800/TwoProgressBars.png --- * 概要 [#summary] ひとつの`SwingWorker`で、進捗を表示する`JProgressBar`をふたつ使用します。 #download(https://lh6.googleusercontent.com/-S6ko35_DIi8/TfWPa08dHvI/AAAAAAAAA9I/MNhC-0LF8YQ/s800/TwoProgressBars.png) * サンプルコード [#sourcecode] #code(link){{ enum ComponentType { TOTAL, FILE, LOG } class Progress { public final Object value; public final ComponentType componentType; public Progress(ComponentType componentType, Object value) { this.componentType = componentType; this.value = value; } } // ... worker = new SwingWorker<String, Progress>() { private final Random r = new Random(); @Override public String doInBackground() throws InterruptedException { int current = 0; int lengthOfTask = 12; // filelist.size(); publish(new Progress(ComponentType.LOG, "Length Of Task: " + lengthOfTask)); publish(new Progress(ComponentType.LOG, "\n------------------------------\n")); publish(new Progress(ComponentType.LOG, "\n--------------------------\n")); while (current < lengthOfTask && !isCancelled()) { if (!bar1.isDisplayable()) { return "Disposed"; } convertFileToSomething(); publish(new Progress(ComponentType.LOG, "*")); publish(new Progress(ComponentType.TOTAL, 100 * current / lengthOfTask)); current++; } publish(new Progress(ComponentType.LOG, "\n")); return "Done"; } private void convertFileToSomething() throws InterruptedException { int current = 0; int lengthOfTask = 10 + r.nextInt(50); // long lengthOfTask = file.length(); int lengthOfTask = 10 + r.nextInt(50); // = file.length(); while (current <= lengthOfTask && !isCancelled()) { int iv = 100 * current / lengthOfTask; Thread.sleep(20); // dummy Thread.sleep(20); publish(new Progress(Component.FILE, iv + 1)); current++; } } @Override protected void process(List<Progress> chunks) { for (Progress s: chunks) { switch (s.componentType) { case TOTAL: bar1.setValue((Integer) s.value); break; case FILE: bar2.setValue((Integer) s.value); break; case LOG: area.append((String) s.value); break; } } } // ... }} * 解説 [#explanation] 上記のサンプルでは、デフォルトで用意されている`SwingWorker#setProgress(int)`は使用せず、以下の`3`つのコンポーネントの状態を表す`Progress`クラスを作成し、これを`SwingWorker<String, Progress>#publish(Progress)`メソッドに与えて`EDT`上でそれぞれの状態を更新しています。 - 全体の進捗を表示する`JProgressBar` - 個々のファイル処理(このサンプルではランダムに`Thread.sleep(...)`を実行するだけ)の進捗を表示する`JProgressBar` - ログを表示する`JTextArea` ---- - `SwingWorker`に別の`PropertyChangeListener`を追加する方法もある #code{{ worker.firePropertyChange("file-progress", iv, iv + 1); // ... class SubProgressListener implements PropertyChangeListener { private final JProgressBar progressBar; public SubProgressListener(JProgressBar progressBar) { this.progressBar = progressBar; this.progressBar.setValue(0); } @Override public void propertyChange(PropertyChangeEvent e) { String strPropertyName = e.getPropertyName(); if ("file-progress".equals(strPropertyName)) { int progress = (Integer) e.getNewValue(); progressBar.setValue(progress); } } } }} * 参考リンク [#reference] - [[SwingWorkerを使った処理の中断と進捗状況表示>Swing/SwingWorker]] - [[SwingWorkerの一時停止と再開>Swing/PauseResumeSwingWorker]] * コメント [#comment] #comment #comment