Swing/PauseResumeSwingWorker のバックアップ(No.8)
- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- Swing/PauseResumeSwingWorker へ行く。
- 1 (2012-12-19 (水) 22:10:17)
- 2 (2013-10-22 (火) 15:10:12)
- 3 (2014-03-28 (金) 13:43:10)
- 4 (2014-12-02 (火) 01:32:14)
- 5 (2015-03-27 (金) 21:46:26)
- 6 (2015-03-28 (土) 15:35:05)
- 7 (2016-11-21 (月) 19:07:15)
- 8 (2017-11-26 (日) 23:47:48)
- 9 (2018-02-24 (土) 19:51:30)
- 10 (2019-05-22 (水) 19:35:38)
- 11 (2019-07-19 (金) 17:09:54)
- 12 (2021-03-23 (火) 02:24:13)
- 13 (2024-02-10 (土) 17:48:05)
- category: swing
folder: PauseResumeSwingWorker
title: SwingWorkerの一時停止と再開
tags: [SwingWorker, JProgressBar, JTextArea]
author: aterai
pubdate: 2011-07-25T14:41:32+09:00
description: SwingWorkerで処理の一時停止と再開を行います。
image:
hreflang:
href: http://java-swing-tips.blogspot.com/2011/07/pause-and-resume-swingworker.html lang: en
概要
SwingWorker
で処理の一時停止と再開を行います。
Screenshot
Advertisement
サンプルコード
class RunAction extends AbstractAction {
public RunAction() {
super("run");
}
@Override public void actionPerformed(ActionEvent evt) {
final JProgressBar bar1 = new JProgressBar(0, 100);
final 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>() {
@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 final Random r = new Random();
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
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");
}
}
View in GitHub: Java, Kotlin解説
SwingWorker#doInBackground()
内のループで一時停止のフラグを参照し、一時停止状態の場合は本来の処理(上記のサンプルではカウントアップするだけ)を行わずに、Thread.sleep(...)
と停止中を表現するコンポーネントの更新(JTextArea
の文字列を点滅)のみ繰り返すようになっています。