---
category: swing
folder: TextAreaOutputStream
title: JTextAreaにLoggerのログを出力する
tags: [JTextArea, OutputStream, StreamHandler, Logger]
author: aterai
pubdate: 2015-02-16T00:00:51+09:00
description: Loggerのログ出力をJTextAreaに表示するためのOutputStreamとStreamHandlerを作成します。
image: https://lh3.googleusercontent.com/-SjJO0dTl1jg/VOChTiK0lPI/AAAAAAAANw4/elD2Gb4uBd0/s800/TextAreaOutputStream.png
hreflang:
    href: https://java-swing-tips.blogspot.com/2015/02/logging-into-jtextarea.html
    lang: en
---
* 概要 [#summary]
`Logger`のログ出力を`JTextArea`に表示するための`OutputStream`と`StreamHandler`を作成します。

#download(https://lh3.googleusercontent.com/-SjJO0dTl1jg/VOChTiK0lPI/AAAAAAAANw4/elD2Gb4uBd0/s800/TextAreaOutputStream.png)

* サンプルコード [#sourcecode]
#code(link){{
class TextAreaOutputStream extends OutputStream {
  private final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  private final JTextArea textArea;

  protected TextAreaOutputStream(JTextArea textArea) {
    super();
    this.textArea = textArea;
  }

  @Override public void flush() throws IOException {
    textArea.append(buffer.toString("UTF-8"));
    buffer.reset();
  }

  // // Java 10:
  // @Override public void flush() {
  //   textArea.append(buffer.toString(StandardCharsets.UTF_8));
  //   buffer.reset();
  // }

  @Override public void write(int b) {
    buffer.write(b);
  }

  @Override public void write(byte[] b, int off, int len) {
    buffer.write(b, off, len);
  }
}
}}

* 解説 [#explanation]
- `TextAreaOutputStream`
-- `ByteArrayOutputStream`を使用して`JTextArea`に一行ずつ書き込みを行う
-- これを`System.setOut(new PrintStream(new TextAreaOutputStream(textArea), true, "UTF-8"));`のように標準出力ストリームに割り当てると`System.out.println(...)`などで改行文字が書き込まれたときにバッファの`flush()`が呼び出され、`textArea.append(buf.toString("UTF-8"));`メソッドで`JTextArea`に文字列が追記される
- `TextAreaHandler`
-- ログ出力を上記の`TextAreaOutputStream`などに割り当てるため、`StreamHandler`を継承する`TextAreaHandler`を作成し`Logger#addHandler(...)`で設定
-- `StreamHandler#setEncoding(...)`でエンコーディングを`UTF-8`に設定
-- `StreamHandler#publish(...)`、`StreamHandler#close(...)`をオーバーライド
-- `StreamHandler#getEncoding()`をオーバーライドしてエンコーディングを`UTF-8`に設定
-- `StreamHandler#publish(...)`、`StreamHandler#close(...)`をオーバーライドして`flush()`を実行
#code{{
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(os, new SimpleFormatter());
  }

  public TextAreaHandler(OutputStream os) {
    super();
    configure();
    setOutputStream(os);
  @Override public String getEncoding() {
    return StandardCharsets.UTF_8.name(); // "UTF-8";
  }

  // @see java/util/logging/ConsoleHandler.java
  @Override public void publish(LogRecord record) {
    super.publish(record);
    flush();
  }

  @Override public void close() {
    flush();
  }
}
}}

* 参考リンク [#reference]
- [https://community.oracle.com/thread/1366824 System.out.println() Print to JFrame | Oracle Community]
- [http://www.dreamincode.net/forums/topic/117537-external-program-output-to-jtextarea/ External Program Output To JTextArea - Java | Dream.In.Code]
- [https://altcla.hatenadiary.org/entry/20091029/1256824750 標準出力を JTextArea に出力する - As I like it.]
- [https://tips4java.wordpress.com/2008/11/08/message-console/ Message Console « Java Tips Weblog]

* コメント [#comment]
#comment
#comment