Eclipse RCP 界面概览

Eclipse RCP 简介

Eclipse 是一种基于 Java 的可扩展开源开发平台。就其自身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。同时也是提供了一套完善机制的 Rcp 平台。Eclipse 平台具有一组功能强大的插件(参见图 1),这些插件可支持多种项目,比如 JDT 和 PDE。

图 1.Eclipse 平台体系结构简化图

图中粉红色的部分代表的是 Eclipse 的富客户部平台(Rich Client

Platform,RCP)的核心组件。图中淡蓝色所标示的部分代表的是可包含到基于 RCP

的应用程序中的可选(但建议包含)部件。而灰色部分所示的部件是可选内容。当使用 Eclipse 操作开发企业应用,应使用到以下内容:

运行库 :

运行库是基于 OSGi 规范用来定义 Eclipse 插件模型以及扩展概念和扩展点的代码。运行库还提供了一些额外服务,比如日志和并发性。

JFace/SWT :

标准小部件工具箱(Standard Widget Toolkit,SWT)是一组小部件集,为 Eclipse

提供了其外在感观。JFace 是位于 SWT 之上的一层,提供了一些 模型 - 视图 -

控制器(Model-View-Controller,MVC)类,以使开发图形应用程序更为简单。

工作台 :

工作台为 Eclipse 赋予了个性化。视图、透视图的概念以及编辑器等都在这一层定义。

帮助(用户协助):

Eclipse 组件让您可以为用户提供协助。这可以通过帮助系统实现,该系统允许用户搜索帮助文档,也可以采用备忘单(cheatsheet),它可视为面向终端用户的互动性任务列表。

更新 :

Eclipse 的更新组件提供了可允许您将应用程序从一个版本更新到另一个版本的设施。

RCP 程序界面区域划分

启动 Eclipse,选择默认的工作空间后,弹出的整个窗口称为 Workbench(工作台),其主要由以下几个部分组成:主菜单、工具条、透视图、状态栏。透视图主要由编辑器和视图组成。主要区域划分如下图。

图 2. 界面区域划分(Eclipse IDE 界面)

真实的企业应用项目应构建于 Workbench 之上的,典型的程序界面如下。

图 3 界面区域划分(典型 RCP 业务界面)

可以看出不加修饰的 RCP 程序整体风格朴素、颜色单调,本文通过对界面的美化可以达到如下效果。

图 4 界面美化效果图

Rcp 程序主体区域风格的美化

本章以示例的方式对程序的主体区域进行美化,美化的主要区域包括:菜单区域、工具栏区域、Editorarea 区域、状态栏区域、进度条区域。

创建 RCP 程序示例

首先新建 RCP 的项目,在 eclipse 中新建 RCP 项目非常简单。启动 Eclipse,打开菜单

File->New->Project,选中 Plug-in Project

并且键入工程名。如:rcp.demo。在下一页中,填写此插件的基本属性信息,对于问题 "Would you liketo create a

rich client application?" 选择 Yes。最后,使用所提供的模板 "Hello RCP" 并接受缺省设置来创建一个

RCP 的工程。生成的项目如下。

图 5. 默认生成的 Hello RCP 项目

程序运行后展示的是一个简单的 Workbench 窗口,通过修改 ApplicationWorkbenchWindowAdvisor 类中的 preWindowOpen() 方法将界面主要区域显示出来。

清单 1. 控制界面区域显示代码片段

public void preWindowOpen() {

IWorkbenchWindowConfigurer configurer = getWindowConfigurer();

configurer.setInitialSize(new Point(400, 300));

// 显示工具条区域

configurer.setShowCoolBar(true);

// 显示状态栏区域

configurer.setShowStatusLine(true);

// 显示菜单区域

configurer.setShowMenuBar(true);

// 显示进度条区域

configurer.setShowProgressIndicator(true);

configurer.setTitle("Hello RCP");

}

然后运行程序可以看到如下效果。

图 6. 简单的 Hello RCP 窗口

以图书管理为例增加一个图书管理的菜单和图书入库子菜单以及一个图书入库的工具栏按钮。在 ApplicationActionBarAdvisor 类中修改 fillMenuBar 和 fillCoolBar 方法。代码片段如下。

清单 2. 添加菜单和一个工具栏按钮代码片段

protected void fillCoolBar(ICoolBarManager coolBar) {

ToolBarManager toorbar = new ToolBarManager();

coolBar.add(toorbar);

BookInputAction aciton = new BookInputAction();

aciton.setImageDescriptor(Activator

.getImageDescriptor("icons/bookInput.gif"));

// 添加一个工具栏按钮

toorbar.add(aciton);

}

protected void fillMenuBar(IMenuManager menuBar) {

MenuManager bookManage = new MenuManager("图书管理");

BookInputAction aciton = new BookInputAction();

bookManage.add(aciton);

// 添加一个菜单

menuBar.add(bookManage);

}

菜单区域的美化

获取系统默认生成的菜单区域后,对菜单进行美化。注意到 Menu

类提供公开的设置背景和字体的方法。只是提供了以下包可见的方法。setBackground、setBackgroundImage、

setForeground。通过反射调用这些方法对菜单进行设置。给控件添加背景是尽量用图片,原因是图片更加美观,如果只是通过设置背景色改变背景那

样有时过于单调。在 ApplicationWorkbenchWindowAdvisor 类中添加以下方法。

清单 3. 设置菜单背景图片代码片段

public void setMenuBG(Image mimage) {

// 获取 RCP 框架默认生成的菜单区域对象

org.eclipse.jface.action.MenuManager mm = (MenuManager) ApplicationActionBarAdvisor

getDefault().getMenubar();

Menu menu = mm.getMenu();

// 通过反射给菜单区域添加图片

invoke("setBackgroundImage", menu, new Class[] { Image.class },

new Image[] { mimage });

}

Object invoke(String methodName, Object object, Class>[] argsTypes,

Object[] args) {

Object result = null;

try {

Method m = object.getClass().getDeclaredMethod(methodName,

argsTypes);

m.setAccessible(true);

result = m.invoke(object, args);

} catch (Exception e) {

e.printStackTrace();

}

return result;

}

然后在 ApplicationWorkbenchWindowAdvisor 类 postWindowOpen() 方法中调用一下

setMenuBG(Image mimage) 方法给菜单设置一个背景图片。接下来修改菜单的字体,Menu 中没有相关的设置菜单字体的方法。通过

SWT 提供的 OS 类调用 Windows 的 API 可以修改操作系统的菜单。在

ApplicationWorkbenchWindowAdvisor 类中添加如下方法和字段,代码如下。

清单 4. 修改菜单字体代码片段

/**

给操作系统菜单设置字体

*/

public static void setSystemMenuFont(Font menuFont) {

if (menuFont != null){

cur_info.cbSize = NONCLIENTMETRICSW.sizeof;

if (OS.SystemParametersInfo(OS.SPI_GETNONCLIENTMETRICS, 0,

cur_info, 0)) {

System.out.println("Font:=>"

+ new String(cur_info.lfMenuFont.lfFaceName));

}

LOGFONTW fw = (LOGFONTW) menuFont.getFontData()[0].data;

cur_info.lfMenuFont.lfFaceName = fw.lfFaceName;

cur_info.lfMenuFont.lfHeight = fw.lfHeight;

cur_info.lfMenuFont.lfWidth = cur_info.lfMenuFont.lfWidth;

cur_info.lfMenuFont.lfEscapement = fw.lfEscapement;

cur_info.lfMenuFont.lfOrientation = fw.lfOrientation;

cur_info.lfMenuFont.lfWeight = fw.lfWeight;

cur_info.lfMenuFont.lfItalic = fw.lfItalic;

cur_info.lfMenuFont.lfUnderline = fw.lfUnderline;

cur_info.lfMenuFont.lfStrikeOut = fw.lfStrikeOut;

cur_info.lfMenuFont.lfCharSet = fw.lfCharSet;

cur_info.lfMenuFont.lfOutPrecision = fw.lfOutPrecision;

cur_info.lfMenuFont.lfClipPrecision = fw.lfClipPrecision;

cur_info.lfMenuFont.lfQuality = fw.lfQuality;

cur_info.lfMenuFont.lfPitchAndFamily = fw.lfPitchAndFamily;

cur_info.iMenuHeight = fw.lfHeight;

if (OS.SystemParametersInfo(42, 0, cur_info, 0)) {

System.out.println("iMenuHeight:=>" + cur_info.iMenuHeight);

System.out.println("iMenuHeight:=>"

+ OS.GetSystemMetrics(OS.SM_CYMENU));

// 发送消息修改操作系统的菜单字体

OS.SendMessage(0xffff, OS.WM_SETTINGCHANGE, 0, 0);

} else {

System.out.println("iMenuHeight:=>" + cur_info.iMenuHeight);

System.out.println("iMenuHeight:=>"

+ OS.GetSystemMetrics(OS.SM_CYMENU));

}

}

}

/**

将操作系统的菜单设置为默认值

*/

public static void clearSystemMenuFont() {

if (OS.SystemParametersInfo(OS.SPI_GETNONCLIENTMETRICS, 0, cur_info, 0)) {

System.out.println("test:=>"

+ new String(cur_info.lfMenuFont.lfFaceName));

}

cur_info.lfMenuFont.lfFaceName = org_info.lfMenuFont.lfFaceName;

cur_info.lfMenuFont.lfHeight = org_info.lfMenuFont.lfHeight;

cur_info.lfMenuFont.lfWidth = cur_info.lfMenuFont.lfWidth;

cur_info.lfMenuFont.lfEscapement = org_info.lfMenuFont.lfEscapement;

cur_info.lfMenuFont.lfOrientation = org_info.lfMenuFont.lfOrientation;

cur_info.lfMenuFont.lfWeight = org_info.lfMenuFont.lfWeight;

cur_info.lfMenuFont.lfItalic = org_info.lfMenuFont.lfItalic;

cur_info.lfMenuFont.lfUnderline = org_info.lfMenuFont.lfUnderline;

cur_info.lfMenuFont.lfStrikeOut = org_info.lfMenuFont.lfStrikeOut;

cur_info.lfMenuFont.lfCharSet = org_info.lfMenuFont.lfCharSet;

cur_info.lfMenuFont.lfOutPrecision = org_info.lfMenuFont.lfOutPrecision;

cur_info.lfMenuFont.lfClipPrecision = org_info.lfMenuFont.lfClipPrecision;

cur_info.lfMenuFont.lfQuality = org_info.lfMenuFont.lfQuality;

cur_info.lfMenuFont.lfPitchAndFamily = org_info.lfMenuFont.lfPitchAndFamily;

cur_info.iMenuHeight = org_info.iMenuHeight;

if (OS.SystemParametersInfo(42, 0, cur_info, 0)) {

System.out.println("clear:=>" + cur_info.iMenuHeight);

OS.SendMessage(0xffff, OS.WM_SETTINGCHANGE, 0, 0);

}

}

同样在 ApplicationWorkbenchWindowAdvisor 类 postWindowOpen() 方法中调用一下

setSystemMenuFont(Font menuFont) 为菜单设置一种字体即可。这个方法的缺点是 RCP

程序运行时操作系统的所有菜单全改变了(个别机器系统环境的原因可能无效)。不要忘了在 Application 类中的 stop 方法中调用

clearSystemMenuFont() 方法在程序结束后将菜单样式恢复到系统默认。在 postWindowOpen() 方法中重绘一下

Shell,调用 getWindowConfigurer().getWindow().getShell().redraw() 即可。

重新运行程序显示效果如下。

图 7. 菜单区域美化后的效果图

工具栏区域的美化

和美化菜单的步骤一致,首先获取 RCP 框架中生成的工具栏对象。并对其设置背景图片。然后在 postWindowOpen() 方法中调用。

清单 5. 美化工具栏代码片段

public void setToorbarBG(Image timage) {

Object[] childrens = getWindowConfigurer().getWindow().getShell()

.getChildren();

for (int i = 0; i < childrens.length; i++) {

String clazz = childrens[i].getClass().getName();

// 获取 RCP 框架默认生成的工具条对象

if (clazz.endsWith("CBanner")) {

// 为工具栏设置图片

((Composite) childrens[i]).setBackgroundImage(timage);

((Composite) childrens[i]).setBackgroundMode(SWT.INHERIT_FORCE);

}

}

}

程序运行后效果图如下。

图 8. 工具栏区域美化后的效果图

Editorarea 区域的美化

修改工作区域背景,使程序主体风格一致。首先获取 RCP 框架中生成的 Editorarea 区域代表的对象。并对其设置背景图片。最上面的 tabfolder 标签区需要设置一下颜色。然后在 postWindowOpen() 方法中调用一下。

清单 6. 美化 Editorarea 区域代码片段

public void setEditorTabFolderColor(Color color) {

if (getWindowConfigurer().getWindow() == null) {

return;

}

if (getWindowConfigurer().getWindow().getActivePage() == null) {

return;

}

WorkbenchPage page = (WorkbenchPage) getWindowConfigurer().getWindow()

.getActivePage();

Composite client = page.getClientComposite();

Control[] children = client.getChildren();

Composite child = (Composite) children[0];

Control[] controls = child.getChildren();

for (final Control control : controls) {

// 获取 Editorarea 区域中的 tabfolder 对象

if (control instanceof CTabFolder) {

control.setBackground(color);

}

}

}

public void setEditorAreaBG(Image image) {

if (getWindowConfigurer().getWindow() == null) {

return;

}

if (getWindowConfigurer().getWindow().getActivePage() == null) {

return;

}

WorkbenchPage page = (WorkbenchPage) getWindowConfigurer().getWindow()

.getActivePage();

Composite client = page.getClientComposite();

Control[] children = client.getChildren();

Composite child = (Composite) children[0];

Control[] controls = child.getChildren();

for (final Control control : controls) {

if (control instanceof CTabFolder) {

CTabFolder tabfolder = (CTabFolder) control;

Listener[] listeners = tabfolder.getListeners(SWT.MenuDetect);

if (listeners != null) {

for (int i = 0; i < listeners.length; i++) {

// 屏蔽系统右键菜单

tabfolder.removeListener(SWT.MenuDetect, listeners[i]);

}

}

Listener[] listeners2 = tabfolder.getListeners(SWT.DragDetect);

if (listeners2 != null) {

for (int i = 0; i < listeners2.length; i++) {

// 屏蔽编辑器默认可拖动的属性

tabfolder.removeListener(SWT.DragDetect, listeners2[i]);

}

}

tabfolder.setBackgroundImage(image);

tabfolder.setBackgroundMode(SWT.INHERIT_FORCE);

}

}

}

public void addPartListener(final Color color) {

getWindowConfigurer().getWindow().getActivePage().addPartListener(

new IPartListener() {

public void partActivated(IWorkbenchPart part) {

if (part instanceof EditorPart) {

setEditorTabFolderColor(color);

}

}

public void partBroughtToTop(IWorkbenchPart part) {

if (part instanceof EditorPart) {

setEditorTabFolderColor(color);

}

}

public void partClosed(IWorkbenchPart part) {

if (part instanceof EditorPart) {

setEditorTabFolderColor(color);

}

}

public void partDeactivated(IWorkbenchPart part) {

if (part instanceof EditorPart) {

setEditorTabFolderColor(color);

}

}

public void partOpened(IWorkbenchPart part) {

if (part instanceof EditorPart) {

setEditorTabFolderColor(color);

}

}

});

}

程序运行后效果图如下。

图 9. Editorarea 区域美化后的效果图

状态栏区域的美化

首先获取 RCP 框架中生成的状态栏区域代表的对象。并对其设置背景图片。然后在 postWindowOpen() 方法中调用一下。

清单 7. 美化状态栏区域代码片段

public void setStausLineBG(Image image) {

Object[] childrens = getWindowConfigurer().getWindow().getShell()

.getChildren();

for (int i = 0; i < childrens.length; i++) {

String clazz = childrens[i].getClass().getName();

// 获取 RCP 框架默认生成的状态栏区域对象

if (clazz.endsWith("StatusLine")) {

((Composite) childrens[i]).setBackgroundImage(image);

((Composite) childrens[i]).setBackgroundMode(SWT.INHERIT_FORCE);

}

}

}

程序运行后效果图如下。

图 10. 状态栏区域美化后的效果图

进度指示条区域的美化

首先获取 RCP 框架中生成的进度指示条区域代表的对象。并对其设置背景图片。然后在 postWindowOpen() 方法中调用一下。

清单 8. 进度指示条区域代码片段

public void setProgressIndicatorBG(Image image) {

Object[] childrens = getWindowConfigurer().getWindow().getShell()

.getChildren();

for (int i = 0; i < childrens.length; i++) {

String clazz = childrens[i].getClass().getName();

//RCP 框架默认生成的进度条区域对象

if (clazz.endsWith("ProgressRegion$1")) {

((Composite) childrens[i]).setBackgroundImage(image);

((Composite) childrens[i]).setBackgroundMode(SWT.INHERIT_FORCE);

}

}

}

程序运行后效果图如下。

图 11. 进度指示条区域美化后的效果图

缝隙处是程序默认的颜色,影响了美观。只要给背景的 Shell 设置一下颜色即可。在 postWindowOpen() 方法中加入一下代码。

getWindowConfigurer().getWindow().getShell().setBackground(

new Color(Display.getDefault(), 181, 220, 255));

getWindowConfigurer().getWindow().getShell().setBackgroundMode(

SWT.INHERIT_FORCE);

运行后效果图如下。

图 12. Shell 加背景颜色效果图

界面控件的美化

本章节通过在 Hello RCP 示例的基础上添加图书管理录入页面展示界面的美化。在 SWT 中基本上所有的窗体控件都继承了

Control 类。Control 中提供了

setBackground、setBackgroundImage、setFont、setForeground 等方法用于美化控件。

为 Composite 添加背景

首先我们创建一个简单的图书录入页面。然后需要将我们的页面嵌入到 RCP 程序中的 Editorarea 区域中,新建一个 Editor,并将我们创建的页面放入到 Editor 中。Editor 的相关代码如下。

清单 9. Editor 代码片段

public class BookManageEditor extends EditorPart {

@Override

public void doSave(IProgressMonitor monitor) {

}

@Override

public void doSaveAs() {

}

@Override

public void init(IEditorSite site, IEditorInput input)

throws PartInitException {

setSite(site);

setInput(input);

}

@Override

public boolean isDirty() {

return false;

}

@Override

public boolean isSaveAsAllowed() {

return false;

}

@Override

/**

创建 editor 区域的页面展示区域

*/

public void createPartControl(Composite parent) {

InputComposite input = new InputComposite(parent, SWT.NONE);

}

@Override

public void setFocus() {

}

}

接下来在图书管理菜单下创建一个图书管理的图书录入子菜单,添加一个操作。当点击菜单时将打开我们的图书录入的页面。操作 Action 的相关代码如下。

清单 10. Action 代码片段

public class BookInputAction extends Action {

public BookInputAction() {

super();

super.setText("图书入库");

}

public void run() {

IWorkbench workbench = PlatformUI.getWorkbench();

IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();

WorkbenchPage page = (WorkbenchPage) window.getActivePage();

try {

// 通过 editor 的 id 号打开对应的 editor

page.openEditor(new BookManageEditorInput(), "rcp.demo.editor");

} catch (PartInitException e) {

e.printStackTrace();

}

}

class BookManageEditorInput implements IEditorInput {

public boolean exists() {

return false;

}

public ImageDescriptor getImageDescriptor() {

return null;

}

public String getName() {

return "图书管理";

}

public IPersistableElement getPersistable() {

return null;

}

public String getToolTipText() {

return "图书管理";

}

public Object getAdapter(Class adapter) {

return null;

}

}

}

此时页面背景是 SWT 默认的,通过调用 Composite 的 setBackgroundImage 方法为 Composite 添加背景图片,之后调用一下 setBackgroundMode 让在页面上控件都继承页面的背景。

清单 11. 添加页面背景代码片段

public InputComposite(Composite parent, int style) {

super(parent, style);

// 为页面添加背景

this.setBackgroundImage(Activator.getImageDescriptor(

"icons/content_blue.jpg").createImage());

// 实现背景的继承关系

this.setBackgroundMode(SWT.INHERIT_FORCE);

...

...

}

运行效果如下图。

图 13. 页面效果图

为页面控件添加统一的背景颜色

为了方便管理页面同一类型的控件的风格,我们创建一个工厂类,用于创建页面的控件。我们需要创建控件时通过工厂类获取,而不是每次通过调用控件的构造函数来创建。

清单 12. 控件工厂类代码片段

public class ControlFactory {

public static Font controlFont;

public static Color controlForeColor;

public static Color controlBGColor = new Color(Display.getDefault(), 255,

255, 255);

private ControlFactory() {

}

synchronized public static ControlFactory getDefault() {

if (instance == null) {

instance = new ControlFactory();

}

return instance;

}

/**

创建 label 控件

*/

public Label createLabel(Composite parent, int style) {

Label label = new Label(parent, style);

if (controlFont != null) {

label.setFont(controlFont);

}

if (controlForeColor != null) {

label.setForeground(controlForeColor);

}

if (controlBGColor != null) {

label.setBackground(controlBGColor);

}

return label;

}

/**

创建 text 控件

*/

public Text createText(Composite parent, int style) {

Text text = new Text(parent, style);

if (controlFont != null) {

text.setFont(controlFont);

}

if (controlForeColor != null) {

text.setForeground(controlForeColor);

}

if (controlBGColor != null) {

text.setBackground(controlBGColor);

}

return text;

}

/**

创建 combo 控件

*/

public Combo createCombo(Composite parent, int style) {

Combo combo = new Combo(parent, style);

if (controlFont != null) {

combo.setFont(controlFont);

}

if (controlForeColor != null) {

combo.setForeground(controlForeColor);

}

if (controlBGColor != null) {

combo.setBackground(controlBGColor);

}

return combo;

}

}

通过工厂类创建好页面控件后,运行 RCP 项目界面效果如下。

图 14. 控件效果图

利用 GC 实现突出显示

在实际的项目需求中,用户录入后往往要求对录入不符合要求的控件进行标识。控件自身没有提供这个功能,我们需要自己通过 GC 类在控件上画线。在控件中需要通过 addPaintListener 的方法获取一个 GC 对象,通过该对象进行线条绘制。代码如下。

清单 13. GC 绘图代码片段

text_5.addPaintListener(new PaintListener() {

public void paintControl(PaintEvent e) {

GC gc = e.gc;

gc.setLineWidth(3);

gc.setForeground(Display.getDefault().getSystemColor(

SWT.COLOR_RED));

gc.drawRectangle(1, 1, text_5.getSize().x-25, text_5.getSize().y-8);

gc.dispose();

}

});

图 15. GC 效果图

利用首选项全局设置界面风格

对于企业应用程序,应提供系统设置功能,让用户选择喜欢的外观风格和自定义设置。使用 Eclipse 首先项,通过首选项记录用户的自定义设置。每次打开程序时,使用用户所选设置而取代默认值,这样可以很好的实现用户对 RCP 程序整体风格的设置。

创建控件整体风格设置和皮肤设置的首选项

首先需要加一个首选项的扩展,名字为系统风格设置。相应的 plugin .xml 的扩展点片段如下。

清单 14. plugin.xml 的扩展点片段 1

point="org.eclipse.ui.preferencePages">

class="rcp.demo.preferences.SystemPreferencePage"

id="rcp.demo.preferences.SystemPreferencePage"

name="Hello_RCP 系统设置">

新添加一个控件设置的首先项 page。可以对控件的背景和字体进行配置。相应的 plugin .xml 的扩展点片段如下。

清单 15. plugin.xml 的扩展点片段 2

id="rcp.demo.preferences.SystemPreferencePage"name="Hello_RCP 系统设置">

class="rcp.demo.preferences.ControlPage" id="rcp.demo.preferences.ControlPage"

新添加一个皮肤设置的首先项 page。可以对皮肤进行配置。相应的 plugin .xml 的扩展点片段如下。

清单 16. plugin.xml 的扩展点片段 3

point="org.eclipse.ui.preferencePages">

class="rcp.demo.preferences.SystemPreferencePage"

id="rcp.demo.preferences.SystemPreferencePage"

name="Hello_RCP 系统设置">

category="rcp.demo.preferences.SystemPreferencePage"

class="rcp.demo.preferences.ControlPage"

id="rcp.demo.preferences.ControlPage"

name="控件设置">

category="rcp.demo.preferences.SystemPreferencePage"

class="rcp.demo.preferences.SkinPage"

id="rcp.demo.preferences.SkinPage"

name="皮肤设置">

所有的 page 相关源码参见本文提供的示例源码。

首选项对话框与菜单关联

创建一个 Action 关联到菜单上用于打开首选项对话框。

清单 17. 打开首选项对话框 Action 代码片段

public class OpenPreferencesDialogAction extends Action {

protected String[] ids = new String[] { "rcp.demo.preferences.ControlPage",

"rcp.demo.preferences.SkinPage" };

public OpenPreferencesDialogAction(String[] ids) {

super();

this.setText("系统设置");

if (ids != null) {

this.ids = ids;

}

}

public void run() {

PreferenceDialog dialog;

// 打开 eclipse 中提供的首选项设置对话框

dialog = PreferencesUtil.createPreferenceDialogOn(null,

"rcp.demo.preferences.SystemPreferencePage", ids, null);

dialog.getShell().setText("系统设置");

if (dialog.open() == 0) {

MessageDialog confrim = new MessageDialog(Display.getDefault()

.getActiveShell(), "确认信息", null,

"需要重启应用程序才能生效 !", MessageDialog.QUESTION, new String[] {

IDialogConstants.OK_LABEL, IDialogConstants.CANCEL_LABEL },

0);

if (confrim.open() == 0) {

PlatformUI.getWorkbench().restart();

}

}

}

}

图 16. 首选项对话框

创建 LookAndFeel 类管理系统风格

为了统一管理系统的字体,颜色,皮肤的风格,创建一个 LookAndFeel

类给系统提供字体,颜色,图片等。程序中菜单区域、工具栏区域、editorarea

区域、状态栏区域、进度条区域的图片和颜色,还包括页面的背景色,控件的字体和颜色都由该类提供。用户设置的风格属性保存到本地文件后,通过

LookAndFeel 类读取,并根据用户的设置给系统提供不同的字体、颜色和图片。LookAndFeel 类的相关代码可以参见本文的示例程序。

Rcp 程序控件整体风格设置

修改上一章中创建的控件工厂类,在创建控件的方法内部,通过 LookAndFeel 类为控件提供字体和背景。创建 Text 控件的代码片段举例如下。

清单 18. 通过 LookAndFeel 管理控件风格代码片段

// 在构造函数中通过 LookAndFeel 获取控件字体和背景信息

private ControlFactory() {

controlFont = LookAndFeel.getDefault().getControlFont();

controlForeColor = LookAndFeel.getDefault().getFontColor();

controlBGColor = LookAndFeel.getDefault().getControlBGColor();

labelBGColor = LookAndFeel.getDefault().getLabelBGColor();

lableForeColor = LookAndFeel.getDefault().getFontColor();

}

// 创建 Text 时为其设置背景和字体

public Text createText(Composite parent, int style) {

Text text = new Text(parent, style);

if (controlFont != null) {

text.setFont(controlFont);

}

if (controlForeColor != null) {

text.setForeground(controlForeColor);

}

if (controlBGColor != null) {

text.setBackground(controlBGColor);

} else {

text.setBackground(Display.getDefault().getSystemColor(

SWT.COLOR_WHITE));

}

return text;

}

完成相关代码后,可以通过首选项对控件风格进行设置。

图 17. 控件风格设置图

程序重启后读取首选项数据,使用前文所述方法修改程序外观,程序展示如下效果。

图 18. 控件风格效果图

实现换肤

实现换肤就是为 RCP 程序主体区域提供多套不同的背景图片,这些图片通过 LookAndFeel 类获取,该类根据用户的选择为程序主体区域提供不同的菜单。以菜单区域为例,代码片段如下。

清单 19. 通过 LookAndFeel 提供菜单背景图片代码片段

//LookAndFeel 类中该方法用于提供菜单区域背景图片

public Image getMenuImage() {

if (LookAndFeel.TYPE_BLUE.equals(LookAndFeel.CURRENT_TYPE)) {

return Activator.getImageDescriptor("icons/menu_blue.jpg")

.createImage();

} else if (LookAndFeel.TYPE_PURPLE.equals(LookAndFeel.CURRENT_TYPE)) {

return Activator.getImageDescriptor("icons/menu_purple.jpg")

.createImage();

} else {

return Activator.getImageDescriptor("icons/menu_blue.jpg")

.createImage();

}

}

完成相关代码后,可以通过首选项对皮肤进行选择。

图 19. 皮肤设置图

程序提示重启后,运行效果如下。

图 20. 换肤效果图

结束语

Eclipse 从某种意义上可以看作一个完善机制的 RCP

平台,由于其优秀的插件机制,近年来越来越多的被应用于企业应用项目。但由于开发人员更关注业务系统功能,而不注重程序美观性,使 EclipseRCP

程序难以得到用户的青睐。本文通过笔者在实际项目中的开发经验,介绍了简单的美化 Eclipse RCP 程序的方法,希望能对使用 Eclipse

平台的技术人员有所启发。

java rcp中lable设置透明_RCP界面美化技术(转)相关推荐

  1. 在Java程序设计中,设置环境变量path和classpath的作用分别是什么?

    在Java程序设计中,设置环境变量path和classpath的作用分别是什么? asd79308 10级  分类: 编程开发  被浏览344次  2013.07.22 额,你这问题问的有够" ...

  2. notepad设置背景颜色_Word2017中如何设置透明背景图和取消背景图

    如何在Word2017中设置透明背景图 1.打开Word文档 2.选择"插入"-"形状",选择并绘制你所需要的背景图形状 3.选中所绘的形状,点击右键,选择&q ...

  3. ❤️Java实现模拟QQ(消息通信+登陆界面美化)❤️

    一.登陆界面的实现 登陆界面主要使用了JFrame,以及相关的一些组件,并且在界面中加上监听 登陆界面效果图 登陆界面代码Login类 package com.lding.login;import c ...

  4. java expires_java 中Cookie设置Expires的问题

    项目开发中遇到一个问题,保存第三方跳转过来的url所带的参数到cookie,并持久化到本地.若是使用Servlet 使用的api,会致使某些时候cookie没法存在本地的问题,所以本次修改,改成set ...

  5. qt设置文本背景透明_qml文件中怎么设置透明输入框

    import QtQuick 2.2 Rectangle { width: 360 height: 360 color: "#6666FF" Loader{ anchors.cen ...

  6. 阿里面试官的分享Java面试中需要准备哪些多线程并发的技术要点

    在任何Java面试当中多线程和并发方面的问题都是必不可少的一部分.所以你应该准备很多关于多线程的问题.在投资银行业务中多线程和并发是一个非常受欢迎的话题,特别是电子交易发展方面相关的.他们会问面试者很 ...

  7. java编程中的点_Java的21个技术点和知识点归纳(转)

    1. JVM相关(包括了各个版本的特性) 对于刚刚接触Java的人来说,JVM相关的知识不一定需要理解很深,对此里面的概念有一些简单的了解即可.不过对于一个有着3年以上Java经验的资深开发者来说,不 ...

  8. java 爬中 验证码识别_JAVA爬虫---验证码识别技术(一)

    Python中有专门的图像处理技术比如说PIL,可以对验证码一类的图片进行二值化处理,然后对图片进行分割,进行像素点比较得到图片中的数字.这种方案对验证码的处理相对较少,运用相对普遍,很多验证码图片可 ...

  9. java mariadb 使用,java连接mariaDB的设置,java连接mariadb

    java连接mariaDB的设置,java连接mariadb java连接mariaDB数据库的设置:(tomcat 8) 第一种方法:使用tomcat自带的mysql-connector-java- ...

最新文章

  1. pda找不到服务器,PDA连不上服务器常见问题分析.doc
  2. XML篇---可配置化的取值方式[便于维护]
  3. 计算机组成与结构实验箱,HQFC-B1计算机组成和数字电路实验箱
  4. jquery 乱码 传参_jquery获取URL中参数解决中文乱码问题的两种方法
  5. pagehelper 不分页几种情况的解决方法
  6. linux 拿shell,linux下备份拿shell[渗透必备]
  7. tomcat9 启动中提示 org.apache.catalina.webresources.Cache.getResource Unable to add t
  8. Java SSM篇2——框架的基本认识
  9. 【转】单元测试基础知识
  10. 无惧杀入红海市场 ZUK手机底气在哪?
  11. 计算机组成原理写一个运算器,计算机组成原理运算器的实现实验报告.doc
  12. mybatis中#{}和${}
  13. 【Python-3.3】字典存储调查问卷
  14. 关于local storage及session storage 应用问题
  15. RFID FDX HDX Technology
  16. BLE蓝牙的连接和配对过程
  17. AI算法可帮助因气候变化而流离失所的数百万难民找到新家了!
  18. 基于auto.js的微信朋友圈自动点赞脚本
  19. 基于Go语言Iris+Layui的OA办公系统
  20. 亨利福特真的说过“faster horse”么?

热门文章

  1. plink的文件格式
  2. 不能通过ip或Navicat连接mysql及palo的终级解决办法
  3. Echarts中 vab-chart 以全局组件使用时,获取Echarts实例,使用this.myChart.setOption ()
  4. cocos2d-x 不同层控制精灵以及碰撞检测
  5. 【已解决】异常断电文件损坏clickhouse启动不了:filesystem error Structure needs cleaning
  6. GPRS 基站定位 LAC CID 得到经度 纬度及百度地图显示
  7. 虚拟技术应用——网络虚拟商城系统(续)
  8. ECK安装elasticsearch集群及es配置x-pack
  9. 计算机网络八股文背诵版(收藏夹吃灰系列)
  10. 关于git的常用操作