OSDN Git Service

スタートアップ処理の改善
[jindolf/Jindolf.git] / src / main / java / jp / sfjp / jindolf / log / SwingDocHandler.java
index 5933331..c9686e7 100644 (file)
@@ -7,17 +7,22 @@
 
 package jp.sfjp.jindolf.log;
 
+import java.awt.EventQueue;
 import java.util.logging.Formatter;
 import java.util.logging.Handler;
 import java.util.logging.Level;
 import java.util.logging.LogRecord;
 import java.util.logging.SimpleFormatter;
+import javax.swing.text.AttributeSet;
 import javax.swing.text.BadLocationException;
 import javax.swing.text.Document;
 
 /**
- * Swingテキストコンポーネント用データモデル{@link javax.swing.text.Document}
+ * Swingテキストコンポーネント用データモデル
+ * {@link javax.swing.text.Document}
  * に出力する{@link java.util.logging.Handler}。
+ * <p>スレッド間競合はEDTで解決される。
+ * <p>一定の文字数を超えないよう、古い記録は消去される。
  */
 public class SwingDocHandler extends Handler{
 
@@ -48,6 +53,40 @@ public class SwingDocHandler extends Handler{
     }
 
     /**
+     * ドキュメント末尾に文字列を追加する。
+     * <p>EDTから呼ばなければならない。
+     * @param logMessage 文字列
+     */
+    private void appendLog(String logMessage){
+        try{
+            this.document.insertString(this.document.getLength(),
+                                       logMessage,
+                                       (AttributeSet) null );
+        }catch(BadLocationException e){
+            assert false;
+        }
+        return;
+    }
+
+    /**
+     * ドキュメント先頭部をチョップして最大長に納める。
+     * <p>EDTから呼ばなければならない。
+     */
+    private void chopHead(){
+        int docLength = this.document.getLength();
+        if(docLength <= DOCLIMIT) return;
+
+        int offset = docLength - CHOPPEDLEN;
+        try{
+            this.document.remove(0, offset);
+        }catch(BadLocationException e){
+            assert false;
+        }
+
+        return;
+    }
+
+    /**
      * {@inheritDoc}
      * @param record {@inheritDoc}
      */
@@ -56,25 +95,16 @@ public class SwingDocHandler extends Handler{
         if( ! isLoggable(record) ){
             return;
         }
+
         Formatter formatter = getFormatter();
-        String message = formatter.format(record);
-        try{
-            this.document.insertString(this.document.getLength(),
-                                       message,
-                                       null );
-        }catch(BadLocationException e){
-            assert false;
-        }
+        final String message = formatter.format(record);
 
-        int docLength = this.document.getLength();
-        if(docLength > DOCLIMIT){
-            int offset = docLength - CHOPPEDLEN;
-            try{
-                this.document.remove(0, offset);
-            }catch(BadLocationException e){
-                assert false;
+        EventQueue.invokeLater(new Runnable(){
+            public void run(){
+                appendLog(message);
+                chopHead();
             }
-        }
+        });
 
         return;
     }