首先這里主要用到的是org.eclipse.ui.console這個包,所以現在順道先來了解一下:
org.eclipse.ui.console是一個可擴展的console視圖插件,利用它可以實現各種console,并把它們顯示出來。該插件本身就實現了一個Message Console,對于只需要進行消息輸出的RCP應用來說,其功能已經足夠:
- 調用ConsolePlugin.getDefault().getConsoleManager()得到一個IConsoleManager引用
- 創建所需的MessageConsole,并把它(們)加入到上一步得到的Console Manager里
- 調用MessageConsole.newMessageStream()得到連接這個Console的輸出流(MessageConsoleStream)
- 通過MessageConsoleStream的print,println方法進行消息的輸出。當然需要把Console View打開才能看到輸出,可以利用Window/Show View來打開,或者把該View在放到自己實現的Perspective的初始布局中
下面簡要列舉其設計及實現要點:
- 作為一個通用的console及其顯示的框架,org.eclipse.ui.console定義了以下幾個接口:
- IConsole. 代表一個Console,主要方法是createPage,用來創建該Console在Console View中的分頁
- IConsole Manager. 代表一個Console Manager,對Console進行管理
- IConsoleListener. 代表一個Console Listener,當Console被加進Console Manager中或從中刪除時會得到通知
- IConsoleView. 代表Console View,用來顯示各個Console
- org.eclipse.ui.console 本身實現了一個Console View,通過在org.eclipse.ui.views擴展點上擴展的方式。該實現已經相當一般化,一般情況下是不需要實現自己的Console View的.它的實現類是ConsoleView,是一個 PageBookView,每個Console以一個Page的方式呈現,效果就是我們在eclipse里看到的那個Console標簽頁。
- Console 和PageBookView Page的關系。簡言之,就是MVC中Model和View的關系,Model是Console,Page負責把它顯示出來。對于TextConsole 和TextConsolePage,這種Model-View關系是通過TextConsole和(TextConsolePage所關聯的)TextConsoleViewer之間的 Model-View關系來實現的,如圖所示。再看TextConsole和TextConsoleViewer的Model-View關系的實現:TextConsole關聯一個 ConsoleDocument,實現了IDoucment接口,而 TextConsoleViewer是一個TextViewer,在其構造函數中設置其Document為TextConsole關聯的 Document(ConsoleDocument),由此可以看出,TextConsole和TextConsolePage之間的Model-View關系最終還是由jface text框架的IDocument和TextViewer之間的Model-View 關系來實現的。Console和其Page的關系是通過IConsole的createPage方法來建立的,比如,TextConsole的 createPage創建的TextConsolePage對象保存了相應TextConsole對象的引用;對于MessageConsole來說,由于它沒有覆蓋IOConsole的createPage方法,因此創建的是一個IOConsolePage對象, 該IOConsolePage對象保存的雖然是一個TextConsole引用,但其實際類型是MessageConsole。
- 當向第1步得到的Console Manager里加Console時,如果此時ConsoleView已經實例化,則它會是該Console Manager 的一個Console Listener,因此會受到consolesAdded的事件通知,ConsoleView對此事件的處理是調用相應 Console的createPage方法創建一個IPageBookViewPage并顯示它。如果ConsoleView是以后實例化的,則它實例化時會從Console Manager取到當前在Console Manager中的所有Console,對每個Console創建一個 IPageBookViewPage。
- MessgaeConsole是一個IOConsole,IOConsole用于顯示I/O流里的Text;而IOConsole又是一個TextConsole,TextConsole是一個抽象的文本Console,支持正則表達式匹配和超級鏈接,它包含一個Document,概念上就是 jface text框架中的文檔概念,其實現類是ConsoleDocument。MessageConsole.createPage返回的實際上是一個 IOConsolePage,其createControl方法的實現創建了一個IOConsoleViewer,該viewer是jface text框架的TextViewer,其Document被設置為這個MessageConsole的Document,因此當MessageConsole的 Document改變時, 其Page上的TextViewer將反映該變化。
- IOConsole關聯一個Doucment Partitioner(IConsoleDocumentPartitioner),該接口擴展自jface text框架中的 IDocumentPartitioner,其實現類是IOConsolePartitioner.當通過MessageConsoleStream往 MessageConsole上輸出消息時,消息實際進入了這個IOConsolePartitioner內部保存的一個消息列表里。IOConsolePartitioner里實現了一個Job Scheduling,其效果就是不斷檢查該消息列表,把其中的消息添加到MessageConsole的Document的末尾,當然這個工作是在另外的 線程中作的。此時如果ConsoleView已實例化,則該MessageConsole會和其Page上IOConsoleViewer相關聯,因此消息便能在該Console的Page中顯示出來了。
添加依賴:
MessageConsole console = null;MessageConsoleStream consoleStream = null;IConsoleManager consoleManager = null;final String CONSOLE_NAME = "naonConsole";private void initConsole() {consoleManager = ConsolePlugin.getDefault().getConsoleManager();IConsole[] consoles = consoleManager.getConsoles();if (consoles.length > 0) {System.out.println("consoles.length > 0");console = (MessageConsole) consoles[0];} else{System.out.println("consoles.length = 0,new MessageConsole");console = new MessageConsole(CONSOLE_NAME, null);consoleManager.addConsoles(new IConsole[] { console });}consoleStream = console.newMessageStream();}/*** 開啟console, 打印相關消息* @param message 消息內容*/public void printMessage(String message) {if (message != null) {if (console == null) {initConsole();}// 顯示Console視圖consoleManager.showConsoleView(console);// 打印消息consoleStream.print(message + "\n");}}
帶顏色的:private void initConsole() {consoleManager = ConsolePlugin.getDefault().getConsoleManager();IConsole[] consoles = consoleManager.getConsoles();if (consoles.length > 0) {System.out.println("consoles.length > 0");console = (MessageConsole) consoles[0];} else{System.out.println("consoles.length = 0,new MessageConsole");console = new MessageConsole(CONSOLE_NAME, null);consoleManager.addConsoles(new IConsole[] { console });}consoleStream = console.newMessageStream();Display display = Display.getCurrent(); consoleStream.setColor(display.getSystemColor(SWT.COLOR_RED)); }