重定向System.out和System.err到JTextPane,分别用黑色红色显示

把 System.out 和 System.err 重定向到 JTextArea 的做法在网上能找到不少,由于 JTextArea 不能用不同的字体分别显示内容。但我还是希望能象 Eclipse 控制台那样,标准输出为黑色,错误信息为红色,于是选择了 JTextPane 作为输出目的地。线程之间通信息用到了 PipedInputStream 、PipedOutputStream 和 SwingUtilities.invokeLater(new Runnable()。  

自定义了一个 JScrollPane,类名为 ConsolePane,写成的单例类;使用时只需要在你的面板上加上 ConsolePane组件,例如:getContentPane().add(ConsolePane.getInstance(), BorderLayout.CENTER);

界面截图(黑色和红色分别显示 System.out 和 System.err 定向的输出内容):  

RedirectSystemOut.JPG

像控制台那样也设置了最大输出缓冲行数,当超过一定行数后会自动把前面的若干行删除,防止内存占用过大。  

Log4J 与 ConsolePane


作为自己应用程序的输出控制台还是不错的。有个问题,如果要捕获 Log4J 的输出必须选择 1.2.13 或以上的版本的 Log4J,并在 log4j.properties 设置  

 log4j.appender.console.follow = true      #沿用 System.setOut() 或 System.setErr() 设置,默认为 false  

在 1.2.13 以前的 Log4J 的 ConsoleAppender 中没有 follow 属性,Lo4J 不支持 System.out 和 System.err 的分别输出,你可以在 log4j.peroperties 中设置  

lo4j.appender.console.target = System.out   #或 System.err,默认为 System.out  

Log4J 输出信息到控制台要么全到 System.out,要么全到 System.err,也就是在 ConsolePane 中没法分不同颜色显示 log.error() 和 log.debug() 信息。  

这个问题,可以改善的,比如 Eclipse 中就不依赖于 log4j.properties 中怎么设置的。同样在 Eclipse 中也没法让 error 和 debug 信息分不同颜色信息,除非改写 Log4J 的 ConsoleAppender 才能分颜色显示。


下面分别列出 ConsolePane 的实现代码和一个测试代码 TestConsolePane  

1. ConsolePane 代码 

当前还有一些 Bug 未解决:
1. final int len = pi.read(buf); 开始时会产生 java.io.IOException: Write end dead 异常,好像这还是 JDK 本身的 Bug,但不影响使用
2. 输出时有时会缺几个字母,或产生空行
3. 因为实际工作线程来输出,所以输出顺序有时不能保证  

谁有兴趣的话,可以进一步研究一番;可对这个类再做润色,如增加右键菜单,可拷贝、很剪切、清除所有输出、不自动滚动。就像 Eclipse 的控制台那样。  

TestConsolePane 代码 

参考:1. e988. Implementing a Console Window with a JTextArea Component
        2. e989. Inserting Styled Text in a JTextPane Component
        3. e1007. Setting the Font and Color of Text in a JTextPane Using Styles
        4. JEdit syntax 中类 JEditTextArea 的实现

本文链接 https://yanbin.blog/system-out-system-err-jtextpane/, 来自 隔叶黄莺 Yanbin Blog

[版权声明] Creative Commons License 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。

Subscribe
Notify of
guest

1 Comment
Inline Feedbacks
View all comments
ZelluX
16 years ago

这个要赞!