Eclipse插件(RCP)控制台(Console)个性化

背景

如图是Eclipse的控制台,该控制台有一个工具条。工具条使得控制台的功能更加强大。
Eclipse插件(RCP)控制台(Console)个性化_第1张图片

需求

虽然Eclipse提供的控制台强大但在我们自己的RCP中却比较臃肿。因为我们的控制台只想打印文字。
最终简化后的控制台效果如下:
Eclipse插件(RCP)控制台(Console)个性化_第2张图片

实现

引入插件

Eclipse插件(RCP)控制台(Console)个性化_第3张图片
如上图,打开 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) */
@Override public 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);
	}
	
	@Override
	public 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";

	@Override
	public 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插件(RCP)控制台(Console)个性化_第4张图片

测试

启动项目后观察控制台是否打印“软件启动成功!”
效果如下
Eclipse插件(RCP)控制台(Console)个性化_第5张图片
简化后的控制台工具条比较简单,只有三个按钮,从前到后依次为:清空控制台、锁定控制台(暂停滚动)、自动换行。

总结

文章介绍了个性化Eclipse Console(控制台)的一种方法。更好的实现应是充分理解org.eclipse.ui.internal.console 项目的架构、细节等设计后重写一个Consoel,而不是像我这样简单在继承 了ConsoleView 的基础上对功能做一部分裁剪。
我是因为时间原因,如果读者有时间处理,烦请分享。

文中涉及的代码可在项目Epx找到,欢迎fork,start。

你可能感兴趣的:(eclipse插件(RCP),eclipse,Eclipse,plug-in,RCP)