2010-07-27 30 views
4

我需要破解一個小工具。它應該讀取幾個文件並將其轉換。現在在我的IDE中工作。對於用戶,我想添加一個簡單顯示日誌輸出的小UI。Logback + Swing in small tool

你知道一個即時可用的Swing appender logback嗎?或者只是一個文本框和一個「關閉」按鈕,將System.out重定向到一個小UI? PS:我不是在尋找電鋸或拼圖或莉莉絲。我希望在應用程序中顯示日誌消息。

+0

可能重複:http://stackoverflow.com/q/4443878/34088 – 2011-10-07 10:14:40

+1

檢查我的解決方案:http://stackoverflow.com/a/33657637/808901 – 2015-11-11 18:46:09

回答

4

我經常依賴JTextArea#append(),正如example中所建議的那樣。與大多數Swing不同,該方法恰好是線程安全的。

附錄:Console是將System.outSystem.err重定向到JTextArea的相關示例。

+0

我認爲更多問題是如何附加一個可以寫入JTextArea組件的日誌返回appender。我正在努力想弄清楚自己... – 2011-10-07 00:25:09

+0

對不起,我對[Logback](http://logback.qos.ch/)一無所知,但我已經鏈接到一個相關的例子,重定向'System.out '到'JTextArea'。 – trashgod 2011-10-07 02:32:25

+0

不幸的是,最新的['JTextArea'](http://download.oracle.com/javase/7/docs/api/javax/swing/JTextArea.html)似乎已經失去了線程的安全性,因此[EventQueue。 invokeLater()'](http://download.oracle.com/javase/7/docs/api/java/awt/EventQueue.html#invokeLater%28java.lang.Runnable%29)可能是必需的。 – trashgod 2011-10-07 02:34:20

5

你需要編寫自定義的appender類,像這樣:

public class MyConsoleAppender extends AppenderBase<ILoggingEvent> { 
    private Encoder<ILoggingEvent> encoder = new EchoEncoder<ILoggingEvent>(); 
    private ByteArrayOutputStream out  = new ByteArrayOutputStream(); 

    public MyConsoleAppender() { 
    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 
    setContext(lc); 
    start(); 
    lc.getLogger("ROOT").addAppender(this); 
    } 

    @Override 
    public void start() { 
    try { 
     encoder.init(out); 
    } catch (IOException e) {} 
    super.start(); 
    } 

    @Override 
    public void append(ILoggingEvent event) { 
    try { 
     encoder.doEncode(event); 
     out.flush(); 
     String line = out.toString(); // TODO: append _line_ to your JTextPane 
     out.reset(); 
    } catch (IOException e) {} 
    } 
} 

您可以用PatternLayoutEncoder更換EchoEncoder(見的logback實例文件夾CountingConsoleAppender例子)。

編碼器會將每個事件寫入字節緩衝區,然後您可以提取一個字符串並將其寫入您的JTextPane或JTextArea或任何您想要的。

+0

線程安全性如何? – 2012-11-28 01:05:00

0

沒有擔保,但在這裏就是我剛剛寫了一個例子:

/** 
* A Logback appender that appends messages to a {@link JTextArea}. 
* @author David Tombs 
*/ 
public class JTextAreaAppender extends AppenderBase<ILoggingEvent> 
{ 
    private final JTextArea fTextArea; 
    private final PatternLayout fPatternLayout; 

    public JTextAreaAppender(final Context loggerContext, final JTextArea textArea) 
    { 
     fTextArea = textArea; 

     // Log the date, level, class name (no package), and the message. 
     fPatternLayout = new PatternLayout(); 
     fPatternLayout.setPattern("%d{HH:mm:ss.SSS} %-5level - %msg"); 
     fPatternLayout.setContext(loggerContext); 
     fPatternLayout.start(); 

     // Make sure not to call any subclass methods right now. 
     super.setContext(loggerContext); 
    } 

    @Override 
    protected void append(final ILoggingEvent eventObject) 
    { 
     // Actual appending must be done from the EDT. 
     SwingUtilities.invokeLater(new Runnable() { 
      @Override 
      public void run() 
      { 
       final String logStr = fPatternLayout.doLayout(eventObject); 

       // If the text area already has lines in it, append a newline first. 
       if (fTextArea.getDocument().getLength() > 0) 
       { 
        fTextArea.append("\n" + logStr); 
       } 
       else 
       { 
        fTextArea.setText(logStr); 
       } 
      } 
     }); 
    }  
}