`
xtaihcidt
  • 浏览: 1290 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

Eclipse 程序界面美化技术

RCP 
阅读更多
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
             
<extension
point="org.eclipse.ui.preferencePages">
<page
class="rcp.demo.preferences.SystemPreferencePage"
id="rcp.demo.preferences.SystemPreferencePage"
name="Hello_RCP 系统设置">
</page>
</extension>



新添加一个控件设置的首先项 page。可以对控件的背景和字体进行配置。相应的 plugin .xml 的扩展点片段如下。
清单 15. plugin.xml 的扩展点片段 2
             
<extension point="org.eclipse.ui.preferencePages">
<page class="rcp.demo.preferences.SystemPreferencePage"
id="rcp.demo.preferences.SystemPreferencePage"name="Hello_RCP 系统设置">
</page>
<page category="rcp.demo.preferences.SystemPreferencePage"
class="rcp.demo.preferences.ControlPage" id="rcp.demo.preferences.ControlPage"
</page>
</extension>



新添加一个皮肤设置的首先项 page。可以对皮肤进行配置。相应的 plugin .xml 的扩展点片段如下。
清单 16. plugin.xml 的扩展点片段 3
             
<extension
point="org.eclipse.ui.preferencePages">
<page
class="rcp.demo.preferences.SystemPreferencePage"
id="rcp.demo.preferences.SystemPreferencePage"
name="Hello_RCP 系统设置">
</page>
<page
category="rcp.demo.preferences.SystemPreferencePage"
class="rcp.demo.preferences.ControlPage"
id="rcp.demo.preferences.ControlPage"
name="控件设置">
</page>
<page
category="rcp.demo.preferences.SystemPreferencePage"
class="rcp.demo.preferences.SkinPage"
id="rcp.demo.preferences.SkinPage"
name="皮肤设置">
</page>
</extension>



所有的 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 平台的技术人员有所启发
分享到:
评论

相关推荐

    Eclipse 程序界面美化技术_demo.zip

    在ibm网站上是404,找了一下,此处备案!

    Eclipse开发-Android日记本设计源码

    1、用户管理部分,原程序虽然可以注册多个用户,但是每个用户登录进系统后都是一样内容。本次考试要求支持不同用户登录,且每个用户有自己...6、美化部分,在诸如登录界面,日记显示界面等部分,对显示内容进行美化。

    照相机定时拍照程序

    函数名字: 照相机拍照程序 描述: 打算使用定时器实现一个定时拍照的程序,现在程序中还有许多的小bug,这份程序 包还会继续更新!现在只是基本上能够实现功能...3. 美化程序界面; 有你的支持,我将会做得更好!

    基于SQlite制作的图书管理系统已美化

    3. 灵活运用android用户界面UI技术。 4. 熟悉常用的UI组件,UI布局,UI元素。 5. 能够简单的编写界面的布局(XML)文件。 6. 能够简单的编写常用UI组件相关的JAVA代码。 7. 最后根据所学习的知识自己可以编写一个...

    计算机毕业课程设计源码-安卓Android基于Socket简易聊天项目开发

    程序开发工具: Eclipse + 安卓夜神模拟器 一个简单的聊天系统项目,客户端+服务器模式,也就是cs模式,采用java开发语言,服务器端建立Socket监听端口,客户端连接socket发送数据,服务器端将接收到的聊天信息,推...

    Java不同风格的漂亮窗体美化一例

    Java实现不同风格的漂亮窗体,Java美化窗口的例子,即Model-View-Controller结构,本代码将解决如何在一个程序中切换使用各种界面风格,在窗口上放置了几个典型的swing 组件,来演示在不同风格下组件的外观。...

    安卓Android图书管理系统最新美化版可导入AndroidStudio

    ## 系统客户端和服务器端架构技术: 界面层,业务逻辑层,数据层3层分离技术,MVC设计思想! ## 服务器和客户端数据通信格式:json数据格式 系统现在一共2个身份:管理员和读者。在登录界面有个下拉框选择用户身份,...

    基于JAVA的在线考试系统的开发 软件工程与计算机等专业毕业设计 毕业论文

    公司的 Dreamweaver 作为界面美化工具。基本实现了网上考试系统应有的 主要功能模块,包括:管理员的登录,管理和维护;用户注册、登录、注销, 个人信息的查询、修改;考试管理,套题管理,成绩管理。该系统界面简 ...

    基于JAVA的在线考试系统(毕业设计论文)

    公司的 Dreamweaver 作为界面美化工具。基本实现了网上考试系统应有的 主要功能模块,包括:管理员的登录,管理和维护;用户注册、登录、注销, 个人信息的查询、修改;考试管理,套题管理,成绩管理。该系统界面简 ...

    JAVA程序综合设计数据库设计说明.doc

    学会运用AWT和Swing组件美化系统用户界面。 2. 实验环境 XP操作传统、Eclipse开发环境和JDK6.0 3. 实验原理 JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系...

    Java局域网聊天(群聊)小工具(源代码)

    用Java做的针对点对点通信(ServerSocket Socket)的小程序,包括收发信息,用swing开发界面,使用beautyeye美化的界面(高手写的,网上有) 使用说明: 1、将项目在导入eclipse中, 2、先运行...

    基于JAVA的推箱子游戏设计软件程序源码+word毕业论文文档.zip

    基于JAVA的推箱子游戏设计软件程序源码+word毕业论文文档. ...主要开发目标:通过此次研究熟练Java的相关知识和技术的应用,界面美化的工作需要同学的帮助,了解团队和合作的重要,熟悉不同领域相关技术

    中南大学嵌入式课设《我们约会吧》嵌入式课设拓展

    3.2.2 修改app名字和图标美化以及用户登录界面图像的修改 22 3.2.3 app上设计者的信息添加 24 3.2.4 注册界面的提示和提示按钮 26 3.2.5 帮助内容的添加人文关怀 27 3.2.6 确认密码改成了纯文本密码的显示 28 3.2.7...

    JAVA开发的网络聊天室

    用ECLIPSE直接运行就可以了,基于java中的APPLET的技术开发的简单的网络聊天程序,当然界面是用布局管理器做的,不是怎么好看,大家可以直接美化看看

    基于Java的飞机大战游戏的设计与实现设计软件源码+word毕业论文文档.zip

    基于Java的飞机大战游戏的设计与实现设计软件源码+word毕业论文文档。基于Java的飞机大战游戏主要需要我方飞机和敌方...最主要的原因就是不能充分发挥PC机的性能,即游戏程序不能最大化使用PC机的硬件资源,导致PC机

    星座说明书

    本程序段主要进行了查询主界面的设计,界面布局主要括:四个TextView、一个Button及其一个Spinner组件。其中Spinner是用来显示列表项的控件,类似于一组单选框RadioButton也就是下拉菜单。同时,数据的传送是通过...

    android实训报告总结.doc

    于是乎,我们继续编写以后面的功能,以及美化界面,细 " " "化代码,测试功能,以及找出程序中存在的不足,和bug,在修正" " "。在大家的团结努力下,我们成功的完成我们的实训的项目 " " "本次实训让我受益匪浅。 " " "首先...

Global site tag (gtag.js) - Google Analytics