• title: JTextAreaにLoggerのログを出力する tags: [JTextArea, OutputStream, StreamHandler, Logger] author: aterai pubdate: 2015-02-16T00:00:51+09:00 description: Loggerのログ出力をJTextAreaに表示するためのOutputStreamとStreamHandlerを作成します。 hreflang:
       href: http://java-swing-tips.blogspot.com/2015/02/logging-into-jtextarea.html
       lang: en

概要

Loggerのログ出力をJTextAreaに表示するためのOutputStreamStreamHandlerを作成します。

サンプルコード

class TextAreaOutputStream extends OutputStream {
  private final ByteArrayOutputStream buf = new ByteArrayOutputStream();
  private final JTextArea textArea;
  public TextAreaOutputStream(JTextArea textArea) {
    super();
    this.textArea = textArea;
  }
  @Override public void flush() throws IOException {
    super.flush();
    buf.flush();
  }
  @Override public void close() throws IOException {
    super.close();
    buf.close();
  }
  @Override public void write(int b) throws IOException {
    if (b == '\r') {
      return;
    }
    if (b == '\n') {
      final String text = buf.toString("UTF-8");
      buf.reset();
      EventQueue.invokeLater(new Runnable() {
        @Override public void run() {
          textArea.append(text + '\n');
          textArea.setCaretPosition(textArea.getDocument().getLength());
        }
      });
      return;
    }
    buf.write(b);
  }
}
View in GitHub: Java, Kotlin

解説

  • TextAreaOutputStream
    • ByteArrayOutputStreamを使用して、JTextAreaに一行ずつ書き込みを行う
    • System.setOut(new PrintStream(new TextAreaOutputStream(textArea), true, "UTF-8"));のように標準出力ストリームに割り当てると、System.out.printlen("xxxxx")などがJTextAreaに出力されるようになる
  • TextAreaHandler
    • ログ出力を上記のTextAreaOutputStreamなどに割り当てるため、StreamHandlerを継承するTextAreaHandlerを作成し、Logger#addHandler(...)で設定
    • StreamHandler#setEncoding(...)でエンコーディングをUTF-8に設定
    • StreamHandler#publish(...)StreamHandler#close(...)をオーバーライド
class TextAreaHandler extends StreamHandler {
  private void configure() {
    setFormatter(new SimpleFormatter());
    try {
      setEncoding("UTF-8");
    } catch (IOException ex) {
      try {
        setEncoding(null);
      } catch (IOException ex2) {
        // doing a setEncoding with null should always work.
        // assert false;
        ex2.printStackTrace();
      }
    }
  }
  public TextAreaHandler(OutputStream os) {
    super();
    configure();
    setOutputStream(os);
  }
  //@see java/util/logging/ConsoleHandler.java
  @Override public void publish(LogRecord record) {
    super.publish(record);
    flush();
  }
  @Override public void close() {
    flush();
  }
}

参考リンク

コメント