Eclipse插件(RCP)控制台(Console)个性化
背景
如图是Eclipse的控制台,该控制台有一个工具条。工具条使得控制台的功能更加强大。
需求
虽然Eclipse提供的控制台强大但在我们自己的RCP中却比较臃肿。因为我们的控制台只想打印文字。
最终简化后的控制台效果如下:
实现
引入插件
如上图,打开 plugin.xml
,在 Dependencies 中添加插件 org.eclipse.ui.console;bundle-version="3.9.200"
扩展视图
Eclipse 的控制台视图是org.eclipse.ui.internal.console.ConsoleView
,间接继承自ViewPart
,其绘制视图的代码片段如下:
/ * Creates this view's underlying viewer and actions. * Hooks a pop-up menu to the underlying viewer's control, * as well as a key listener. When the delete key is pressed, * the REMOVE_ACTION
is invoked. Hooks help to * this view. Subclasses must implement the following methods * which are called in the following order when a view is * created: * createViewer(Composite)
- the context * menu is hooked to the viewer's control. * createActions()
* configureToolBar(IToolBarManager)
* getHelpContextId()
*
* @see IWorkbenchPart#createPartControl(Composite) */@Overridepublic void createPartControl(Composite parent) {super.createPartControl(parent);createActions();IToolBarManager tbm= getViewSite().getActionBars().getToolBarManager();configureToolBar(tbm);updateForExistingConsoles();getViewSite().getActionBars().updateActionBars();PlatformUI.getWorkbench().getHelpSystem().setHelp(parent, IConsoleHelpContextIds.CONSOLE_VIEW);getViewSite().getPage().addPartListener((IPartListener2)this);initPageSwitcher();}
正常来看,我们只需要仿照这个类实现一个自己的ConsoleView 就可以了,但是Eclipse Console 做了很多封装。因此我们采用继承的方式来对其做一次减法。是的,没错,是使用继承来做一次减法。
- 创建视图类
package com.xzbd.views;import org.eclipse.jface.action.IContributionItem;import org.eclipse.jface.action.IMenuManager;import org.eclipse.jface.action.IToolBarManager;import org.eclipse.swt.widgets.Composite;import org.eclipse.ui.IActionBars;import org.eclipse.ui.IViewSite;import org.eclipse.ui.internal.console.ConsoleManager;import org.eclipse.ui.internal.console.ConsoleView;import com.xzbd.utils.AppPrinter;@SuppressWarnings(value = "restriction")public class MessageConsoleView extends ConsoleView {public static final String ID = "com.xzbd.views.MessageConsoleView";public MessageConsoleView() {super();// 视图初始化时绑定唯一的MessageConsole ConsoleManager consoleManager = (ConsoleManager)AppPrinter.getConsoleManager();consoleManager.registerConsoleView(this);consoleManager.showConsoleView(AppPrinter.getConsole());consoleManager.addConsoleListener(this);}@Overridepublic void createPartControl(Composite parent) {super.createPartControl(parent);IViewSite viewSite = getViewSite();IActionBars actionBars = viewSite.getActionBars();// 隐藏视图菜单IMenuManager menuManager = actionBars.getMenuManager();menuManager.setVisible(false);// 隐藏工具条按钮IToolBarManager toolBarManager = actionBars.getToolBarManager();IContributionItem[] items = toolBarManager.getItems();for(IContributionItem item: items) {item.setVisible(false);}// 更新视图菜单actionBars.updateActionBars();}}
该类继承自ConsoleView
。
因为我们只需要简单的输出消息,所以我们在ViewConsole启动时只绑定MessageConsole控制台。
重写了createPartControl
方法,在其中对视图菜单做了隐藏。
其中AppPrinter
是自定义的一个给Console发送消息的一个工具类。
- 控制台发送消息辅助类AppPrinter
package com.xzbd.utils;import java.util.Objects;import org.eclipse.ui.console.ConsolePlugin;import org.eclipse.ui.console.IConsole;import org.eclipse.ui.console.IConsoleManager;import org.eclipse.ui.console.MessageConsole;import org.eclipse.ui.console.MessageConsoleStream;/ * 应用消息打印器 * * @author xzbd * */public class AppPrinter {public static IConsoleManager getConsoleManager() {return ConsolePlugin.getDefault().getConsoleManager();}public static MessageConsole getConsole() {IConsoleManager consoleManager = getConsoleManager();IConsole[] consoles = consoleManager.getConsoles();if (Objects.isNull(consoles) || consoles.length < 1) {MessageConsole messageConsole = new MessageConsole("", null);consoleManager.addConsoles(new IConsole[] { messageConsole });}IConsole console = consoleManager.getConsoles()[0];return (MessageConsole) console;}/ * 获取新的消息流 * * @return */private static MessageConsoleStream newMessageStream() {return getConsole().newMessageStream();}/ * 打印message并换行 * * @param message */public static void println(String message) {newMessageStream().println(message);}/ * 打印换行 */public static void println() {newMessageStream().println();}/ * 只打印message不换行 * * @param message */public static void print(String message) {newMessageStream().print(message);}}
- 在Plugin.xml中扩展视图
<extension point="org.eclipse.ui.views"> <view class="com.xzbd.views.MessageConsoleView" id="com.xzbd.views.MessageConsoleView" name="控制台" restorable="true"> </view> </extension>
在透视图布局中绑定
打开软件透视图MainPerspective
,在其中绑定MessageConsoleView 视图的布局。
package com.xzbd.perspective;import org.eclipse.ui.IFolderLayout;import org.eclipse.ui.IPageLayout;import org.eclipse.ui.IPerspectiveFactory;import com.xzbd.navigator.MainNavigator;import com.xzbd.views.MessageConsoleView;public class MainPerspective implements IPerspectiveFactory {public static final String ID = "com.xzbd.perspective.MainPerspective";@Overridepublic void createInitialLayout(IPageLayout layout) {layout.setEditorAreaVisible(true);layout.setFixed(false);String editorArea = layout.getEditorArea();// 左侧 导航IFolderLayout leftTopFolder = layout.createFolder("LEFT", IPageLayout.LEFT, 0.18f, editorArea);leftTopFolder.addView(MainNavigator.ID);// 右侧IFolderLayout leftRightFolder = layout.createFolder("RIGHT", IPageLayout.RIGHT, 0.8f, editorArea);leftRightFolder.addView(IPageLayout.ID_OUTLINE);// 添加下部视图IFolderLayout tabs = layout.createFolder("BOTTOM", IPageLayout.BOTTOM, 0.6f, editorArea);// 属性//tabs.addPlaceholder(IPageLayout.ID_PROP_SHEET);// console view 绑定tabs.addView(MessageConsoleView.ID);}}
使用 AppPrinter 给 Console 发送消息
简单起见我们在程序启动完成后在控制台打印:软件启动成功!
重写ApplicationWorkbenchAdvisor
的 postStartup 勾子函数
测试
启动项目后观察控制台是否打印“软件启动成功!”
效果如下
简化后的控制台工具条比较简单,只有三个按钮,从前到后依次为:清空控制台、锁定控制台(暂停滚动)、自动换行。
总结
文章介绍了个性化Eclipse Console(控制台)的一种方法。更好的实现应是充分理解org.eclipse.ui.internal.console
项目的架构、细节等设计后重写一个Consoel,而不是像我这样简单在继承 了ConsoleView 的基础上对功能做一部分裁剪。
我是因为时间原因,如果读者有时间处理,烦请分享。
文中涉及的代码可在项目Epx找到,欢迎fork,start。