• 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: http://java-swing-tips.blogspot.com/2015/02/logging-into-jtextarea.html
       href: https://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 ByteArrayOutputStream buffer = new ByteArrayOutputStream();
  private final JTextArea textArea;
  public TextAreaOutputStream(JTextArea textArea) {
#spanadd

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

#spanend
  @Override public void flush() throws IOException {
    textArea.append(buf.toString("UTF-8"));
    buf.reset();
    textArea.append(buffer.toString("UTF-8"));
    buffer.reset();
  }
  @Override public void write(int b) throws IOException {
    buf.write(b);
#spanadd

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

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

#spanend
  @Override public void write(byte[] b, int off, int len) {
    buffer.write(b, off, len);
  }
}
View in GitHub: Java, Kotlin

解説

解説

  • TextAreaOutputStream
    • ByteArrayOutputStreamを使用して、JTextAreaに一行ずつ書き込みを行う
    • これをSystem.setOut(new PrintStream(new TextAreaOutputStream(textArea), true, "UTF-8"));のように標準出力ストリームに割り当てると、System.out.printlen("xxxxx")などで改行文字が書き込まれたときに、バッファーのflush()が呼び出され、textArea.append(buf.toString("UTF-8"));JTextAreaに文字列が追記される
    • 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(...)をオーバーライド
  • ログ出力を上記のTextAreaOutputStreamなどに割り当てるため、StreamHandlerを継承するTextAreaHandlerを作成しLogger#addHandler(...)で設定
  • StreamHandler#getEncoding()をオーバーライドしてエンコーディングをUTF-8に設定
  • StreamHandler#publish(...)StreamHandler#close(...)をオーバーライドしてflush()を実行
    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);
        super(os, new SimpleFormatter());
      }
      //@see java/util/logging/ConsoleHandler.java
    #spanadd
    
    #spanend
      @Override public String getEncoding() {
        return StandardCharsets.UTF_8.name(); // "UTF-8";
      }
    #spanadd
    
    #spanend
      // @see java/util/logging/ConsoleHandler.java
      @Override public void publish(LogRecord record) {
        super.publish(record);
        flush();
      }
    #spanadd
    
    #spanend
      @Override public void close() {
        flush();
      }
    }
    

参考リンク

参考リンク

コメント

コメント