一、解決基本問題:
在做 RCP 項目的時候經常會遇到一個問題,就是要將一些控制信息輸出到 RCP 自身的控制臺,那么我們就可以擴展 Eclipse 擴展點 org.eclipse.ui.console.consoleFactories ,來實現我們自己的控制臺,解決方法如下:
首先 ,在 plugin.xml 中定義擴展點:
plugin.xml:
<extension
point="org.eclipse.ui.console.consoleFactories">
<consoleFactory
class="com.hnjchina.intro.ConsoleFactory"
label=" 控制臺 "/>
</extension>
其次 ,在 perspective 中加入 console View ,作為控制信息的控制臺( console ):
在 Perspective .java 類中的 Public void createInitialLayout(IPageLayout layout) 方法中加入如下:
ConsoleFactory cf = new ConsoleFactory();
layout.addView(IConsoleConstants.ID_CONSOLE_VIEW, IPageLayout.BOTTOM,0.70f, layout.getEditorArea());
cf.openConsole();
最后 ,自定義 ConsoleFactory 類,主要實現 showConsole() 方法,然后在要輸出信息的地方定義 printer 變量如下:
private MessageConsoleStream printer =ConsoleFactory.console.newMessageStream();
自定義的 ConsoleFactory 類具體代碼如下:
2
3 import java.io.IOException;
4 import java.io.PrintStream;
5 import org.eclipse.ui.console.ConsolePlugin;
6 import org.eclipse.ui.console.IConsole;
7 import org.eclipse.ui.console.IConsoleFactory;
8 import org.eclipse.ui.console.IConsoleManager;
9 import org.eclipse.ui.console.MessageConsole;
10 import org.eclipse.ui.console.MessageConsoleStream;
11
12 /** *//**
13 * 描述:樣式顯示控制臺視圖
14 * */
15 public class ConsoleViewPart implements IConsoleFactory

16
17 private static MessageConsole console = new MessageConsole("樣式顯示窗口", null);
18
19 /** *//**
20 * 描述:打開控制臺
21 * */
22 public void openConsole() {
23 showConsole();
24 }
25
26 /** *//**
27 * 描述:顯示控制臺
28 * */
29 public static void showConsole() {
30 try

31 if (console != null) {
32 //得到默認控制臺管理器
33 IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
34 //得到所有的控制臺實例
35 IConsole[] existing = manager.getConsoles();
36 boolean exists = false;
37 //新創建的MessageConsole實例不存在就加入到控制臺管理器,并顯示出來
38 for (int i = 0; i < existing.length; i++) {
39 if (console == existing[i])
40 exists = true;
41 }
42 if(!exists)

43 System.out.println("aaaaaaaa");
44 manager.addConsoles(new IConsole[] { console });
45 }
46 manager.showConsoleView(console);
47 MessageConsoleStream stream = console.newMessageStream();
48 stream.write("測試!");
49 System.setOut(new PrintStream(stream));
50 }
51 } catch (IOException e) {
52 e.printStackTrace();
53 }
54 }
55
56 /** *//**
57 * 描述:關閉控制臺
58 * */
59 public static void closeConsole() {
60 IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
61 if (console != null) {
62 manager.removeConsoles(new IConsole[] { console });
63 }
64 }
65
66 public static MessageConsole getConsole()

67 return console;
68 }
69
70 }
71
重用 Console 有兩種辦法:
1 、作為組件來重用:
//getConsole 就是 new MessageConsole("", null);
mainConsole = ConsoleFactory.getConsole();
mainTab = new TabItem(tabFolder, SWT.NONE);
TextConsoleViewer tcv = new TextConsoleViewer(tabFolder, mainConsole);
mainTab.setText(" 主線程 ");
mainTab.setControl(tcv.getControl());
MessageConsoleStream printer = mainConsole.newMessageStream();
printer.setColor(Display.getCurrent() .getSystemColor(SWT.COLOR_BLACK));
ConsoleFactory.java :
public static MessageConsole getConsole() {
return new MessageConsole("", null);
}
2 、作為 view 重用:
<extension
id="Hapcent.ConsoleFactory"
name="Console Factory"
point="org.eclipse.ui.console.consoleFactories">
<consoleFactory
class="edu.fudan.hapcent.UI.ConsoleFactory"
icon="icons/sample2.gif"
label="Hapcent.consoleFactory"/>
</extension>
ConsoleFactory.java :
關鍵是一個方法:
public void openConsole() {
IConsoleManager manager = ConsolePlugin.getDefault().getConsoleManager();
IConsole[] existing = manager.getConsoles();
boolean exists = false;
for (int i = 0; i < existing.length; i++) {
if (console == existing)
exists = true;
}
if (!exists) {
manager.addConsoles(new IConsole[] { console });
}
manager.showConsoleView(console );
}
三、經常遇到的錯誤:
在顯示視圖時遇到如下錯誤:
java.lang.NoClassDefFoundError: org/eclipse/ui/console/IConsoleFactory
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(Unknown Source)
……
<!-- [endif]-->
首先,應該檢查在上圖位置的地方是否加入需要的插件,即: org.eclipse.ui.console
2 .在 Dependences 里面已經加入了運行需要的包,但是將 RCP 作為一個 eclipse 項目來運行時還是報錯,而在項目的 .product 文件里先配置好運行需要用到的包,然后用 launch the product 選項 test 項目,可以運行:
這是運行配置的問題,作為項目運行的時候是使用的以前的配置,而那個配置里面沒有添加這個包。同樣道理,如果以后你再添加了其他的包而沒有在你現在 .product 文件中添加的話,它同樣不會自動添加,所以也會出問題。所以這是應該看看你運行時的這個地方有沒有勾上 org.eclipse.ui.console ,如下圖:
另外,在項目的 .product 文件里有一個 Synchronize, 點擊這里可以同步你的運行配置
3 .當顯示 Eclipse 自身的控制臺后,狀態欄的內容沒有了:
分析:調用 IStatusLineManager.setMessage(String message) 會將信息寫入 Eclipse 狀態欄的共享區域,其他的插件例如 Console 也可以對這個區域進行修改,這樣當第一次選中 Console 時,原有狀態欄中的信息就會被清除。
解決:解決的方法是自己實現一個 IContributionItem ,并在 fill(Composite parent) 方法中定義其布局,然后在 ActionBarAdvisor.fillStatusLine(IStatusLineManager statusLine) 中調用 statusLine.add(IContributionItem item) 將其加入 Eclipse 的狀態欄即可。
4 . 如何默認就是自己實現的控制臺,通常情況下默認的控制臺不是自己擴展的那個,而非得在視圖里切換一下才行,還有就是能否把控制臺視圖里的那些ACTION不顯示出來?
解決: 調用openConsole() 就可以默認顯示你自己擴展的控制臺了
四、自定義控制臺,向其輸出 RCP 中的一些實時信息:

public static final String ID = "com.winscad.view.SystemInfoView";
String strGetRespone = "";
Text textSysInfo;
/** *//**
* Create contents of the view part
* @param parent
*/
@Override
public void createPartControl(Composite parent)

final Composite container = new Composite(parent, SWT.NONE);
//設置面板布局
container.setLayout(new FillLayout());
//創建帶有水平和垂直滾動條的文本框
textSysInfo = new Text(container,SWT.BORDER|SWT.V_SCROLL|SWT.H_SCROLL);
//設置文本框的滾動條一直處于最下端
textSysInfo.setTopIndex(0);
final Timer timer = new Timer(true);
//設置每隔1秒去讀一次業務返回的響應數據,并循環顯示(刷新)
timer.scheduleAtFixedRate(new TimerTask()

public void run()

Display.getDefault().asyncExec(new Runnable()

public void run()

}
});
}}, 6*1000, 1*1000);
createActions();
initializeToolBar();
initializeMenu();
}
/** *//**
* Create the actions
*/
private void createActions()

// Create the actions
}
/** *//**
* Initialize the toolbar
*/
private void initializeToolBar()

IToolBarManager toolbarManager = getViewSite().getActionBars().getToolBarManager();
Action deleteAction = new Action()

public void run()

textSysInfo.setText("");
}
};
deleteAction.setText(Message.getString("ParameterView.Clear"));//清空
deleteAction.setToolTipText(Message.getString("ParameterView.ClearSystem"));//清空系統信息
deleteAction.setImageDescriptor(PlatformUI.getWorkbench().getSharedImages().
getImageDescriptor(ISharedImages.IMG_TOOL_DELETE));
toolbarManager.add(deleteAction);
//為ToolBarManager添加自定義控件
ComboContribution combo = new ComboContribution("Combo.contribution");
toolbarManager.add(combo);
toolbarManager.add(new ComboContribution2());
}
//自定義控件
class ComboContribution extends ControlContribution

public ComboContribution(String id)

super(id);
}
@Override
protected Control createControl(Composite parent)

Combo combo = new Combo(parent, SWT.READ_ONLY);
combo.setItems(new String[]

combo.addSelectionListener(new SelectionListener()

public void widgetDefaultSelected(SelectionEvent e)

// TODO Auto-generated method stub
}
public void widgetSelected(SelectionEvent e)

// TODO Auto-generated method stub
textSysInfo.append("View工具欄測試!");
}
});
return combo;
}
}
//自定義控件
class ComboContribution2 extends ContributionItem

private ToolItem toolitem;
private Combo fFindCombo;
private Button upFindbutton;
private Button downFindbutton;
private Button allFindbutton;
public ComboContribution2()

super();
}
protected Control createControl(Composite parent)

Composite composite = new Composite(parent, SWT.NONE);
//查詢框
fFindCombo = new Combo(composite,SWT.NONE);
fFindCombo.setLocation(0, 2);
fFindCombo.setSize(130,20);
System.out.println(" fFindCombo == " + fFindCombo.getBounds());
//向上查
upFindbutton = new Button(composite, SWT.NONE);
upFindbutton.setLocation(135, 2);
upFindbutton.setSize(30,20);
upFindbutton.setText("上查");
upFindbutton.addSelectionListener(new SelectionListener()

public void widgetDefaultSelected(SelectionEvent e)

// TODO 自動生成方法存根
}
public void widgetSelected(SelectionEvent e)

fFindCombo.add(fFindCombo.getText());
}
});
System.out.println(" upFindbutton == " + upFindbutton.getBounds());
//向下查
downFindbutton = new Button(composite, SWT.NONE);
downFindbutton.setLocation(170, 2);
downFindbutton.setSize(30,20);
downFindbutton.setText("下查");
//全部查詢
allFindbutton = new Button(composite, SWT.NONE);
allFindbutton.setLocation(205, 2);
allFindbutton.setSize(30,20);
allFindbutton.setText("全部");
toolitem.setWidth(240);
return composite;
}
public void fill(ToolBar parent, int index)

toolitem = new ToolItem(parent, SWT.SEPARATOR, index);
Control control = createControl(parent);
toolitem.setControl(control);
}
}
/** *//**
* Initialize the menu
*/
private void initializeMenu()

IMenuManager menuManager = getViewSite().getActionBars()
.getMenuManager();
}
@Override
public void setFocus()

// Set the focus
}
public String getStrGetRespone()

return strGetRespone;
}
public void setStrGetRespone(String strGetRespone)

this.strGetRespone = strGetRespone;
}
}
原文出自: