Swing/ProgressMonitorInputStream のバックアップの現在との差分(No.1)
TITLE:ProgressMonitorInputStreamを使用してテキストファイルのダウンロード状況を表示
Posted by aterai at 2013-04-22
ProgressMonitorInputStreamを使用してテキストファイルのダウンロード状況を表示
`ProgressMonitorInputStream
`を使用してテキストファイルのダウンロード状態を進捗表示します。
- category: swing folder: ProgressMonitorInputStream title: ProgressMonitorInputStreamを使用してテキストファイルのダウンロード状況を表示 tags: [ProgressMonitorInputStream, ProgressMonitor, JProgressBar, SwingWorker, URLConnection, JTextArea] author: aterai pubdate: 2013-04-22T03:35:42+09:00 description: ProgressMonitorInputStreamを使用してテキストファイルのダウンロード状態を進捗表示します。 image:
概要
ProgressMonitorInputStream
を使用してテキストファイルのダウンロード状態を進捗表示します。
- &jnlp;
- &jar;
- &zip;
Screenshot
Advertisement
サンプルコード
サンプルコード
#spandel
worker = new SwingWorker<String, Chunk>() {
#spanend
@Override public String doInBackground() {
Charset cs = Charset.forName("EUC-JP");
String ret = "Done";
String path = "http://terai.xrea.jp/";
URLConnection urlConnection;
try{
urlConnection = new URL(path).openConnection();
System.out.println(urlConnection.getContentEncoding());
System.out.println(urlConnection.getContentType());
#spanadd
class RunAction extends AbstractAction {
#spanend
public RunAction() {
super("Load");
}
String encoding = urlConnection.getContentEncoding();
if(encoding!=null) {
cs = Charset.forName(encoding);
}else{
String contentType = urlConnection.getContentType();
for(String value: contentType.split(";")) {
value = value.trim();
if(value.toLowerCase().startsWith("charset=")) {
encoding = value.substring("charset=".length());
}
}
if(encoding!=null) {
cs = Charset.forName(encoding);
}
}
System.out.println(cs);
}catch(Exception ex) {
ex.printStackTrace();
ret = "Error";
return ret;
@Override public void actionPerformed(ActionEvent e) {
runButton.setEnabled(false);
textArea.setText("");
URLConnection urlConnection = getURLConnection();
if (urlConnection == null) {
return;
}
Charset cs = getCharset(urlConnection, "UTF-8");
int length = urlConnection.getContentLength();
try(InputStream is = urlConnection.getInputStream();
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(frame, "Loading", is);
BufferedReader reader = new BufferedReader(new InputStreamReader(pmis, cs))) {
#spandel
#spanend
JFrame frame = (JFrame) SwingUtilities.getWindowAncestor(
(Component) e.getSource());
try {
InputStream is = urlConnection.getInputStream();
ProgressMonitorInputStream pmis = new ProgressMonitorInputStream(
frame, "Loading", is);
monitor = pmis.getProgressMonitor();
monitor.setNote(" "); //Need for JLabel#getPreferredSize
monitor.setMillisToDecideToPopup(0);
monitor.setMillisToPopup(0);
monitor.setMinimum(0);
monitor.setMaximum(length);
#spandel
#spanend
int i = 0;
int size = 0;
String line;
while((line = reader.readLine()) != null) {
if(i++%50==0) { //Wait
Thread.sleep(10);
}
size += line.getBytes(cs).length + 1; //+1: \n
String note = String.format("%03d%% - %d/%d%n", 100*size/length, size, length);
publish(new Chunk(line, note));
}
}catch(InterruptedException | IOException ex) {
ret = "Exception";
cancel(true);
worker = new MonitorTask(pmis, cs, length);
worker.execute();
} catch (IOException ex) {
ex.printStackTrace();
}
return ret;
}
#spanadd
}
#spanend
#spanadd
#spanend
#spanadd
private class MonitorTask extends Task {
#spanend
public MonitorTask(ProgressMonitorInputStream pmis, Charset cs, int length) {
super(pmis, cs, length);
}
#spanadd
#spanend
@Override protected void process(List<Chunk> chunks) {
for(Chunk c: chunks) {
textArea.append(c.line+"\n");
for (Chunk c : chunks) {
textArea.append(c.line + "\n");
monitor.setNote(c.note);
//System.out.println(c.note);
}
textArea.setCaretPosition(textArea.getDocument().getLength());
}
#spanadd
#spanend
@Override public void done() {
frame.getGlassPane().setVisible(false);
runButton.setEnabled(true);
String text = null;
try{
try {
if (pmis != null) {
pmis.close();
}
text = isCancelled() ? "Cancelled" : get();
}catch(Exception ex) {
} catch (IOException | InterruptedException | ExecutionException ex) {
ex.printStackTrace();
text = "Exception";
}
System.out.println(text);
}
#spandel
};
#spanend
#spandel
worker.execute();
#spanend
#spanadd
}
#spanend
#spanadd
#spanend
#spanadd
private static class Task extends SwingWorker<String, Chunk> {
#spanend
protected final ProgressMonitorInputStream pmis;
protected final Charset cs;
protected final int length;
public Task(ProgressMonitorInputStream pmis, Charset cs, int length) {
super();
this.pmis = pmis;
this.cs = cs;
this.length = length;
}
#spanadd
#spanend
@Override public String doInBackground() {
String ret = "Done";
try (Scanner scanner = new Scanner(
new BufferedReader(new InputStreamReader(pmis, cs)))) {
int i = 0;
int size = 0;
while (scanner.hasNextLine()) {
if (i % 50 == 0) { //Wait
Thread.sleep(10);
}
i++;
String line = scanner.nextLine();
size += line.getBytes(cs).length + 1; //+1: \n
String note = String.format(
"%03d%% - %d/%d%n", 100 * size / length, size, length);
//System.out.println(note);
publish(new Chunk(line, note));
}
} catch (InterruptedException | IOException ex) {
System.out.println("Exception");
ret = "Exception";
cancel(true);
}
return ret;
}
#spanadd
}
#spanend
View in GitHub: Java, Kotlin解説
上記のサンプルでは、`URLConnection
から開いた
InputStream
に
ProgressMonitorInputStream
をラップして、ファイルのダウンロード進捗状態を
ProgressMonitor
`で表示しています。
解説
上記のサンプルでは、URLConnection
から開いたInputStream
にProgressMonitorInputStream
をラップして、ファイルのダウンロード進捗状態をProgressMonitor
で表示しています。
- `
ProgressMonitorInputStream
の使用する
ProgressMonitor
`の最大値は、ファイルサイズ(バイト)- `
ProgressMonitorInputStream
がデフォルトで設定する最大値は、
InputStream#available()
`の値 - この値がダウンロード中のストリームの合計バイト数を返す訳ではないので、これを最大値のままにしておくと、`
ProgressMonitor
`が表示されない、またはすぐ閉じてしまう - `
URLConnection#getContentLength()
で取得したバイト数を
ProgressMonitor#setMaximum(...)
`で設定
- `
- 一行ずつ`
JTextArea
に文字列として読み込ませるために、
InputStreamReader
を使用しているので、エンコードを
URLConnection#getContentEncoding()
や
URLConnection#getContentType()
`などで取得- 何パーセント読み込んだかを`
ProgressMonitor#setNote(...)
で表示する場合は、一行が何バイトかを
String#getBytes(Charset)
`で取得して計算 - 注: 改行は`
1
`バイトで決め打ちしている - 進捗を表示する前に`
ProgressMonitor#setNote("dummy note");
としておかないと、
Note
に使用する
JLabel
が
null
`のままで表示されない、またはレイアウトがおかしくなる
- 何パーセント読み込んだかを`
-
ProgressMonitorInputStream
の使用するProgressMonitor
の最大値はファイルサイズ(バイト)-
ProgressMonitorInputStream
がデフォルトで設定する最大値はInputStream#available()
の値 - この値がダウンロード中のストリームの合計バイト数を返す訳ではないので、これを最大値のままにしておくと
ProgressMonitor
が表示されない場合がある -
URLConnection#getContentLength()
で取得したバイト数をProgressMonitor#setMaximum(...)
で設定
-
-
1
行ずつJTextArea
に文字列として読み込ませるためにInputStreamReader
を使用しているので、エンコーディングをURLConnection#getContentEncoding()
やURLConnection#getContentType()
などで取得- 何パーセント読み込んだかを
ProgressMonitor#setNote(...)
で表示する場合は1
行が何バイトかをString#getBytes(Charset)
で取得して計算 - このサンプルでは改行は
LF
のみの1
バイトであると決め打ちしている - 進捗を表示する前に
ProgressMonitor#setNote("temp note");
と適当な文字列を設定しておかないとNote
に使用するJLabel
がnull
のままで表示されない、またはレイアウトがおかしくなる
- 何パーセント読み込んだかを