最近为一个项目的服务器的做一个界面的时候,为了能把原来在后台打印出来的相关信息重定向到GUI界面的时候,费了一些心思。都是以前在实现的时候大多数信息的打印和测试时使用的都是System.out和System.err之类,图个方便 ,没有使用log功能。当然这是个不好的习惯。
刚 开始的时候用Swing做了一个面板,采用JTextPane组件作为打印信息的容器。可能是太久没有用Swing了,在测试的时候这个东西的水平滑动块 老是随着信息的显示自动地滑向最后的地方,而且打印信息看起来很凌乱。后来就换用SWT,把打印的信息容器换用Text组件,把样式定义为 SWT.MULT | SWT.V_SCROLL | SWT.WRAP ,让它可以自动换行。
查一下JDK的API文档,System类 提供了可以重定向的方法setOut(PrintStream out)、setErr(PrintStream err)、setIn(InputStream in)。在此我们只需求使用setOut和setErr就够了,这二个方法都要传入一个PrintStream类型的参数,只要在调用打印信息的前面调用 这二个方法重设输出流和错误流就可以达到我们的目的。那么我们继承PrintStream类,并把要显示信息的组件作为参数传入到这个自定义的打印流类 中。
2
3 private Text text;
4
5 public MyPrintStream(OutputStream out, Text text) {
6 super (out);
7 this .text = text;
8 }
9
10 /** */ /**
11 * 在这里重截,所有的打印方法都要调用的方法
12 */
13 public void write( byte [] buf, int off, int len) {
14 final String message = new String(buf, off, len);
15
16 /**/ /* SWT非界面线程访问组件的方式 */
17 Display.getDefault().syncExec( new Thread() {
18 public void run() {
19 /**/ /* 在这里把信息添加到组件中 */
20 text.append(message);
21 }
22 } );
23 }
24
25 }
把组件作为参数传入到这个打印流中,并重写父类的write(byte[] buf, int off, int len)方法,把写出的信息添加到组件上,注意到重载了带OutputStream的构造方法。
这里有二点必须注意,确保组件在调用打印信息添加前是已经被正确创建的,另外必须注册不同GUI组件对线程的访问形式,像上面的SWT就对界面的访问有严格的规定。
完成了PrintStream后,下面是如何使用,在我们启动界面后,使用下面的方式:
2 System.setOut(mps);
3 System.setErr(mps);
,这样就可以把原来程序里的所有System.out和System.err信息转移到你的GUI界面上。
原文地址:http://www.blogjava.net/nighty/archive/2007/08/27/140100.html