以前在使用Java開發項目時,曾遇到這麼一種情景:在一個Eclipse外掛程式工程中,當外掛程式運行後進行多線程模擬執行,這時需要捕獲並輸出Java的標準輸出資料流和錯誤流。
1. 解決思路
Java中System類提供了可以重新導向的方法setOut(PrintStream out)、setErr(PrintStream err)、setIn(InputStream in)。因此,使用setOut和setErr就夠了,這二個方法都要傳入一個PrintStream類型的參數,只要在調用列印資訊的前面調用這二個方法重設輸出資料流和錯誤流就可以達到我們的目的。因此,通過繼承PrintStream類,並把要顯示資訊的組件作為參數傳入到這個自訂的列印流類PrintStream中。
2. 程式碼範例View Code
1 /**
2 * @author ypf
3 * @version 1.0
4 * Created on 2009-11-4
5 * Description: the override PrintStream for catching Java standard
6 * console output to SWT dialog's Text control.
7 */
8 publicclass ConsolePrintStream extends PrintStream {
9 private Text text;
10
11 public ConsolePrintStream(OutputStream out, Text text) {
12 super(out);
13 this.text = text;
14 }
15
16 /**
17 * 重截write方法,所有的列印方法都要調用的方法
18 */
19 publicvoid write(byte[] buf, int off, int len) {
20 final String message =new String(buf, off, len);
21 if (text !=null&&!text.isDisposed()) {
22 /* SWT非介面線程訪問組件的方式 */
23 Display.getDefault().syncExec(new Thread() {
24 publicvoid run() {
25 /* 在這裡把資訊添加到組件中 */
26 text.append(message);
27 }
28 });
29 } else {
30 super.write(buf, off, len);
31 }
32 }
33 }
注意:確保GUI組件在調用列印資訊添加前已經被正確建立的,另外必須註冊不同GUI組件對線程的訪問形式,像上面的SWT就對介面的訪問有嚴格的規定。
3. 使用方法
在啟動GUI介面程式之後,按照如下方式調用代碼:
View Code
1 ConsolePrintStream cps=new ConsolePrintStream(System.out, text); // text為GUI組件
2
3 System.setOut(cps);
4
5 System.setErr(cps);
之後,Java標準輸出和標準錯誤就被重新導向到設定的GUI組件上了。