- PR -

コンソール出力について

投稿者投稿内容
toshi
会議室デビュー日: 2007/05/24
投稿数: 11
投稿日時: 2007-05-24 20:48

>2.FileWriterで書き出して、動作中に出力されているか?

「長い処理」は別スレッドで処理するようにしておいて、以下のコードで試してみました.

File logFile=new File("xxxx-log.txt");
FileOutputStream logOutStream=new FileOutputStream(logFile);
PrintStream logPrintStream=new PrintStream(logOutStream, true);
System.setOut(logPrintStream);
System.setErr(logPrintStream);

"xxxx-log.txt"には全メッセージが正常に書き込まれていました.完璧でした.とすると悪いのはやはり私の作った

public class JTextAreaOutputStream extends ByteArrayOutputStream

ということになります.

以上

nagise
ぬし
会議室デビュー日: 2006/05/19
投稿数: 1141
投稿日時: 2007-05-24 21:01
サンプルを書いてみたのでどうぞ。
コード:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class SwingTest {
	public static void main(String[] args) {
		final JFrame frame = new JFrame();
		frame.setSize(640, 480);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		JTextArea textArea = new JTextArea();
		frame.getContentPane().add(textArea);

		// System.out にJTextAreaOutputStreamに書き出すPrintStreamを設定
		OutputStream os = new JTextAreaOutputStream(textArea, "UTF-8");
		System.setOut(new PrintStream(os, true)); // 自動flushをtrueにしておく

		// JFrameの表示
		SwingUtilities.invokeLater(new Runnable(){
			public void run() {
				frame.setVisible(true);
			}
		});

		// System.outへの書き出し。
		for (int i=0; i<10; i++) {
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(i);
		}
	}

	/** JTextAreaに書き出すOutputStream */
	public static class JTextAreaOutputStream extends OutputStream {
		private ByteArrayOutputStream os;
		/** 書き出し対象 */
		private JTextArea textArea;
		private String encode;

		public JTextAreaOutputStream(JTextArea textArea, String encode) {
			this.textArea = textArea;
			this.encode = encode;
			this.os = new ByteArrayOutputStream();
		}
		/** OutputStream#write(byte[])のオーバーライド */
		public void write(int arg) throws IOException {
			this.os.write(arg);
		}
		/**
		 * flush()でJTextAreaに書き出す
		 */
		public void flush() throws IOException {
			// 文字列のエンコード
			final String str = new String(this.os.toByteArray(), this.encode);
			// 実際の書き出し処理
			SwingUtilities.invokeLater(new Runnable(){
				public void run() {
					JTextAreaOutputStream.this.textArea.append(str);
				}
			});
			// 書き出した内容はクリアする
			this.os.reset();
		}
	}
}



引用:

未記入さんの書き込み (2007-05-24 19:18) より:
SwingUtilities.invokeLater() の説明は概ね正しいのですが、ここで SwingUtilities.invokeLater() を使えというのは半分 不正解ですよ。50点。


なるほど、処理が別スレッドなのを暗黙の前提と思っていましたが
確認していないですから注意を払うべきところでした。
toshi
会議室デビュー日: 2007/05/24
投稿数: 11
投稿日時: 2007-05-24 21:23
nagise様

サンプルをいただきましてどうもありがとうございます.

私の書いたコードはinvokeLater()のパラメータになるRunnable()のインスタンスを使いまわしていたのが悪かったようです.ちょうどさっき以下のコードでまともに動いてくれました.今度は、ログは全部まともにJTextAreaに出力されるようになりました.

まだ何か悪いところがあるかもしれませんが、とりあえず私のも載せておきます.でもflushのトリガでやった方がスマートですね.本当にいろいろありがとうございました.

public class JTextAreaOutputStream extends ByteArrayOutputStream {
private JTextArea jtextArea;
private AddToTextArea addTextArea;

public JTextAreaOutputStream(JTextArea jtextArea){
super();
this.jtextArea=jtextArea;
addTextArea=new AddToTextArea();
this.addTextArea.setJtextArea(this.jtextArea);
}

public synchronized void write(byte[] b, int off, int len){
super.write(b, off, len);
appendString();
this.reset();
}

public synchronized void write(byte[] b) throws IOException{
super.write(b);
appendString();
this.reset();
}

public synchronized void write(int b){
super.write(b);
appendString();
this.reset();
}
/**
* Append text to JTextArea
*/
private synchronized void appendString(){
String outputStr=this.toString();
AddToTextArea addToTextArea=new AddToTextArea();
addToTextArea.setJtextArea(this.jtextArea);
addToTextArea.setOutputStr(outputStr);
SwingUtilities.invokeLater(addToTextArea);
}
}

class AddToTextArea implements Runnable{
private JTextArea jtextArea;
private String outputStr;
public void setJtextArea(JTextArea jtextArea){
this.jtextArea=jtextArea;
}
public void setOutputStr(String outputStr){
this.outputStr=outputStr;
}
public void run(){
jtextArea.append(outputStr);
}
}

以上

スキルアップ/キャリアアップ(JOB@IT)