Swing/PauseResumeSwingWorker の変更点
- 追加された行はこの色です。
- 削除された行はこの色です。
- Swing/PauseResumeSwingWorker へ行く。
- Swing/PauseResumeSwingWorker の差分を削除
--- category: swing folder: PauseResumeSwingWorker title: SwingWorkerの一時停止と再開 tags: [SwingWorker, JProgressBar, JTextArea] author: aterai pubdate: 2011-07-25T14:41:32+09:00 description: SwingWorkerで処理の一時停止と再開を行います。 image: https://lh6.googleusercontent.com/-3BCjKLnQbGM/Ti0AQV5nkwI/AAAAAAAAA_s/RY75ol3pFak/s800/PauseResumeSwingWorker.png hreflang: href: https://java-swing-tips.blogspot.com/2011/07/pause-and-resume-swingworker.html lang: en --- * 概要 [#summary] `SwingWorker`で処理の一時停止と再開を行います。 #download(https://lh6.googleusercontent.com/-3BCjKLnQbGM/Ti0AQV5nkwI/AAAAAAAAA_s/RY75ol3pFak/s800/PauseResumeSwingWorker.png) * サンプルコード [#sourcecode] #code(link){{ class RunAction extends AbstractAction { public RunAction() { super("run"); } @Override public void actionPerformed(ActionEvent evt) { JProgressBar bar1 = new JProgressBar(0, 100); JProgressBar bar2 = new JProgressBar(0, 100); runButton.setEnabled(false); canButton.setEnabled(true); pauseButton.setEnabled(true); statusPanel.removeAll(); statusPanel.add(bar1, BorderLayout.NORTH); statusPanel.add(bar2, BorderLayout.SOUTH); statusPanel.revalidate(); worker = new SwingWorker<String, Progress>() { private final Random r = new Random(); @Override public String doInBackground() { int current = 0; int lengthOfTask = 12; //filelist.size(); publish(new Progress(Component.LOG, "Length Of Task: " + lengthOfTask)); publish(new Progress(Component.LOG, "\n---------------------------\n")); while (current < lengthOfTask && !isCancelled()) { publish(new Progress(Component.LOG, "*")); if (!bar1.isDisplayable()) { return "Disposed"; } try { convertFileToSomething(); } catch (InterruptedException ie) { return "Interrupted"; } publish(new Progress(Component.TOTAL, 100 * current / lengthOfTask)); current++; } publish(new Progress(Component.LOG, "\n")); return "Done"; } private void convertFileToSomething() throws InterruptedException { boolean flag = false; int current = 0; int lengthOfTask = 10 + r.nextInt(50); while (current <= lengthOfTask && !isCancelled()) { if (isPaused) { try { Thread.sleep(500); } catch (InterruptedException ie) { return; } publish(new Progress(Component.PAUSE, flag)); flag ^= true; continue; } int iv = 100 * current / lengthOfTask; Thread.sleep(20); // dummy Thread.sleep(20); publish(new Progress(Component.FILE, iv + 1)); current++; } } @Override protected void process(java.util.List<Progress> chunks) { for (Progress s: chunks) { switch (s.component) { case TOTAL: bar1.setValue((Integer) s.value); break; case FILE: bar2.setValue((Integer) s.value); break; case LOG: area.append((String) s.value); break; case PAUSE: { if ((Boolean) s.value) { area.append("*"); } else { try { Document doc = area.getDocument(); doc.remove(doc.getLength() - 1, 1); } catch (Exception ex) { ex.printStackTrace(); } } break; } } } } @Override public void done() { // ... } }; worker.execute(); } } // ... private boolean isPaused = false; class PauseAction extends AbstractAction { public PauseAction() { super("pause"); } @Override public void actionPerformed(ActionEvent evt) { isPaused = (worker != null && !worker.isCancelled() && !isPaused); JButton b = (JButton) evt.getSource(); b.setText(isPaused ? "resume" : "pause"); } } }} * 解説 [#explanation] 上記のサンプルでは、`SwingWorker#doInBackground()`内のループで一時停止のフラグを参照し、一時停止状態の場合は本来の処理(上記のサンプルではカウントアップするだけ)を行わずに`Thread.sleep(...)`と停止中を表現するコンポーネントの更新(`JTextArea`の文字列を点滅)のみ繰り返す`SwingWorker`を使用しています。 * 参考リンク [#reference] - [[SwingWorkerを使った処理の中断と進捗状況表示>Swing/SwingWorker]] - [[SwingWorkerで複数のJProgressBarを使用する>Swing/TwoProgressBars]] * コメント [#comment] #comment #comment