当前页面: 开发资料首页 → Eclipse 专题 → 探索 Eclipse 的嵌入式富客户端平台
摘要: 本文介绍了嵌入式富客户端平台(embedded Rich Client Platform,eRCP)。将学习构成 eRCP 的各种组件,并得到在应用程序中使用它们的一些示例。
背景
嵌入式富客户端平台(eRCP)的目的是把 Eclipse 的富客户端平台(RCP)带到嵌入式领域。
eRCP 由以下组件构成:
我们将讨论每个组件,并在合适的地方使用代码示例。
eSWT
嵌入式标准部件工具包(eSWT)是著名的 Java™ 图形工具包 —— 标准部件工具包(SWT)—— 的子集。它提供了一套控件、面板和其他常用的部件,作为用户界面的构造块。除了 SWT 中原来包含的部件之外,eSWT 还引入了一个新组件:移动扩展(由 IBM、Nokia 和 Motorola 联合设计的规范),主要针对的是像 PDA 和智能手机这样的移动设备。
从平台独立性的角度来说,eSWT 的设计与它的近亲 SWT 不同。SWT 使用平台独立的方式,试图保持本机代码尽可能简单,以便提高在不同操作系统之间的可移植性。问题在于:可移植性和性能是一对矛盾的问题,所以 eSWT 决定采用另一种方式:通用图形层(UGL),它仍然把 Java 的本机界面(JNI)保留在本机工具包实现上。但是,UGL 没有充当一对一的 JNI 包装器,而试图保持本机实现尽可能接近,只需要通过 JNI 进行回调的信息。eSWT 的方式牺牲了可移植性,因为本机工具包完全依赖于它使用的图形系统,但是这种方式极大地提高了性能(移动设备上的主要考虑因素)。
eSWT 中包含了三个组件(请参阅图 1 ):
核心和扩展组件是 eSWT 的子集。新发明的移动扩展组件针对的是移动设备。这种组件构成方式支持根据设备的能力和目的,灵活地对设备上要包含哪些组件进行配置。核心组件是必需的,包含运行基本应用程序所必需的最小功能。扩展和移动扩展组件是可选的。
在后面的小节中,我们将研究每个组件,同时提供示例应用程序。
eSWT 核心
eSWT 核心包含基本的用户界面元素,包括低级图形、事件和基本的部件基础设施。表 1 显示了 eSWT 核心中的类。
<table border="0" cellpadding="0" cellspacing="0" class="data-table-1" width="">eSWT 核心的示例 我们从一个完整的 eSWT 程序开始,这个程序创建一个窗口,在应用程序的标题栏上显示 “HelloWorld”。然后我们将添加一些核心控件(文本、按钮、列表)。对于布局,我们采用 图 2 显示了在日文版 PocketPC 设备上运行的应用程序。当用户按下 Right Push! 按钮时,就出现一个消息框(如图 3 所示)。eSWT 利用底层的本机图形支持来提供一致的用户界面(本机应用程序的观感,而不是发明一个新外观)。 示例评价 对于清单 1 中的代码实现的效果,值得逐行进行解释。 eSWT 扩展 eSWT 扩展是可选组件,包含多个复杂的用户界面元素和布局。这些功能通常在高端移动设备和 PDA 中才能找到。表 2 显示了 eSWT 扩展中的类的详细列表。 eSWT 扩展的示例 Browser 部件是 eSWT 扩展中一个有意思的部件。我们将用 Broswer 控件创建一个完全能够工作的 Web 浏览器(请参阅清单 2)。在这个示例中将允许用户设置 URL、前进、后退或重新装入页面。 图 4 显示了在 PocktPC 上运行的简单浏览器。 eSWT 移动扩展 eSWT 移动扩展是可选组件,提供了在无数移动设备上常见的用户界面元素。表 3 显示了 eSWT 移动扩展组件中的类。 eSWT 移动扩展示例 在这个示例中,将采用 图 5 显示了在 PocketPC 平台上运行的结果,图 6 显示了全屏幕模式。 eJFace eJFace 是一个依赖 eSWT 的平台独立的用户界面工具包。eJFace 提供了一套组件和辅助工具,可以简化基于 eSWT 的应用程序的开发(通过对 eSWT 部件进行包装),就像 JFace 帮 SWT 做的事一样。实际上,eJFace 是 JFace 的一个严格的子集,所以它与它的近亲有许多相似性。eJFace 提供了对资源管理、查看器、动作和首选项页面的支持。在 参考资料 中有介绍 JFace 的教程,可以帮助您使用 eJFace。 eWorkbench eWorkbench 允许 eRCP 应用程序在一个工作台窗口中同时运行,类似在 RCP 中的工作情况。eWorkbench 客户机提供了特定显示场景的视图,而且 eWorkbench 会自动根据使用的移动设备决定使用哪个视图。在 eWorkbench 中,没有透视图(perspective)的概念 —— 可以把它当成只有一个共享透视图的应用程序 —— 原因是这个概念在嵌入式设备上不适用。 创建 eWorkbench 应用程序只需要几步(RCP 开发人员会很熟悉)。过程与使用 contribution 的概念创建 Eclipse RCP 应用程序的过程类似。 eWorkbench 允许定义三类视图,这三类视图都扩展自 现在创建一个示例视图。 通过使用扩展点机制,让 Eclipse 知道有可用的视图(请参阅清单 5)。 步骤 2:定义 eWorkbench contribution 要成为 eWorkbench 应用程序,必须扩展 org.eclipse.ercp.eworkbench.applications 扩展点,并提供一些信息(请参阅清单 6 中的示例): 图 7 显示了 eWorkbench 应用程序列表的一个挨一个的截屏,后面是刚启动的示例应用程序。 eUpdate RCP 提供的一个优势是用更新管理器界面从中央服务器更新插件的能力。也有与更新管理器关联的特性,例如调度更新。而且,通过使用开放网格服务基础设施(OGSI)和插件,可以动态地安装特性。eRCP 对这些优势的回答是 eUpdate,在编写这篇文章的时候它正在开发当中。 结束语 这篇文章介绍了嵌入式富客户端平台(eRCP)和它的各种组件,提供了示例代码,包括示例 eWorkbench 应用程序和其他可以作为独立示例的代码清单。 下载 参考资料 学习 作者简介<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td colspan="3"></td></tr><tr valign="top" align="left"><td></td><td></td><td width="100%"> Chris Aniszczyk 是 IBM Lotus 的软件工程师和 IBM 的 Extreme Blue 实习项目的毕业生。他是衷心的开放源码支持者,一直在 Gentoo Linux (http://www.gentoo.org)发布方面工作,是 Eclipse Modeling Framework Technology(EMFT)项目的参与者。 Uriel Liu 是 IBM 中国软件开发实验室的软件开发人员,一直从事 WED 客户技术。他也是 eRCP
项目的参与者。
FormLayout
和 FormData
。还将在按钮上添加 SelectionListener
,它将弹出一个消息框。完整的代码如清单 1 所示。
清单 1:eSWAT 风格的 HelloWorld
<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee"><tr><td>
</td></tr></table>
01 public class HelloWorldeSWT {
02
03 public static void main(String[] args) {
04 Display display = new Display();
05 final Shell shell = new Shell(display);
06
07 Text text = new Text(shell,SWT.SINGLE);
08 text.setText("This is a text");
09 Button buttonleft = new Button(shell, SWT.PUSH);
10 buttonleft.setText("Left Push!");
11 Button buttonright = new Button(shell, SWT.PUSH);
12 buttonright.setText("Right Push!");
13 buttonright.addSelectionListener(new SelectionListener(){
14 public void widgetSelected(SelectionEvent e) {
15 MessageBox messageBox = new MessageBox(shell,
16 SWT.ICON_INFORMATION| SWT.YES | SWT.NO);
17 messageBox.setText("MessageBox");
18 messageBox.setMessage("Can you see me?");
19 messageBox.open();
20 }
21 public void widgetDefaultSelected(SelectionEvent e) {
22 }});
23 List list = new List(shell,SWT.MULTI|SWT.BORDER);
24 for (int i=0; i<5; i++) {
25 list.add("item "+i);
26 }
27
28 shell.setText("HelloWorld from eSWT");
29 FormLayout layout = new FormLayout();
30 layout.spacing = 5;
31 layout.marginHeight = layout.marginWidth = 9;
32 shell.setLayout(layout);
33
34 FormData textData = new FormData();
35 textData.top = new FormAttachment(0);
36 textData.left = new FormAttachment(0);
37 textData.right = new FormAttachment(90);
38 text.setLayoutData(textData);
39
40 FormData buttonleftData = new FormData();
41 buttonleftData.top = new FormAttachment(text);
42 buttonleftData.left = new FormAttachment(0);
43 buttonleftData.right = new FormAttachment(40);
44 buttonleft.setLayoutData(buttonleftData);
45
46 FormData buttonrightData = new FormData();
47 buttonrightData.top = new FormAttachment(text);
48 buttonrightData.left = new FormAttachment(buttonleft);
49 buttonright.setLayoutData(buttonrightData);
50 FormData listData = new FormData();
51
52 listData.top = new FormAttachment(buttonleft);
53 list.setLayoutData(listData);
54
55 shell.setSize(240,320);
56 shell.open();
57
58 while (!shell.isDisposed()) {
59 if (!display.readAndDispatch())
60 display.sleep();
61 }
62 display.dispose();
63 }
SelectionListener
中使用它。setText()
来设置文本字符串。SelectionListener
,以弹出一个简单的消息框。FormLayout
、FormData
和 FormAttachment
协助布局过程。setSize()
对顶级窗口不生效(因为设备的原因)。while()
循环内部建立了一个显式循环,不断地读取和分派来自操作系统的用户事件。如果再没有事件发生,就调用 display.sleep()
并进入睡眠,等待下一个事件。display.dispose()
调用显式地清除显示,并释放 eSWT 应用程序的所有相关资源。
清单 2. 简单的 HTML 浏览器
<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee"><tr><td>
</td></tr></table>
public class BrowserTest {
static Button prev, reload, next, go;
static Text url;
static Browser browser;
public static void main(String[] args) {
final Display display = new Display();
Shell shell = new Shell(display);
//set window title and size
shell.setText("SimpleBrowser");
shell.setSize(240,320);
//previous button
prev = new Button(shell, SWT.PUSH);
prev.setText("<<");
prev.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
browser.back();
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
//reload button
reload = new Button(shell, SWT.PUSH);
reload.setText("R");
reload.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
browser.refresh();
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
//next button
next = new Button(shell, SWT.PUSH);
next.setText(">>");;
next.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
browser.forward();
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
// url text
url = new Text(shell, SWT.SINGLE|SWT.BORDER);
url.setText("http://");
// go button
go = new Button(shell, SWT.PUSH);
go.setText("GO");
go.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
// TODO Auto-generated method stub
browser.setUrl(url.getText());
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
// browser
browser = new Browser(shell, SWT.NONE);
browser.setUrl("http://www.google.com");
FormLayout formLayout = new FormLayout();
shell.setLayout(formLayout);
formLayout.spacing = 1;
formLayout.marginHeight = formLayout.marginWidth = 2;
FormData prevData = new FormData();
prevData.left = new FormAttachment(0);
prevData.top = new FormAttachment(0);
prevData.width = 16;
prev.setLayoutData(prevData);
FormData reloadData = new FormData();
reloadData.left = new FormAttachment(prev);
reloadData.top = new FormAttachment(0);
reloadData.width = 16;
reload.setLayoutData(reloadData);
FormData nextData = new FormData();
nextData.left = new FormAttachment(reload);
nextData.top = new FormAttachment(0);
nextData.width = 16;
next.setLayoutData(nextData);
FormData urlData = new FormData();
urlData.left = new FormAttachment(next);
urlData.top = new FormAttachment(0);
urlData.right = new FormAttachment(89);
urlData.bottom = new FormAttachment(browser);
url.setLayoutData(urlData);
FormData goData = new FormData();
goData.left = new FormAttachment(url);
goData.top = new FormAttachment(0);
goData.width = 24;
go.setLayoutData(goData);
FormData browserData = new FormData();
browserData.top = new FormAttachment(prev);
browserData.left = new FormAttachment(0);
browserData.right = new FormAttachment(100);
browserData.bottom = new FormAttachment(100);
browser.setLayoutData(browserData);
shell.open();
while( !shell.isDisposed() ) {
if( !display.readAndDispatch() )
display.sleep();
}
display.dispose();
}
}
MobileShell
代替 Shell
来提供全屏幕功能。MobileShell
在顶部包含一个 SortedList
,在底部包含一个 ListView
。命令与 MobileShell
关联起来,让用户可以改变全屏幕模式,并用 ListView
改变布局的密度。源代码如清单 3 所示。
清单 3. MobileExtension 示例
<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee"><tr><td>
</td></tr></table>
public class MobileExtensionSample implements IPlatformRunnable {
public static void main(String[] args) {
Display display = new Display();
final MobileShell shell = new MobileShell(display);
final Button resetButton = new Button(shell, SWT.PUSH|SWT.BORDER);
Command shellCommand = new Command(shell, Command.SELECT,0);
shellCommand.setText("FullScreen");
shellCommand.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
shell.setFullScreenMode(true);
resetButton.setVisible(true);
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
resetButton.setText("Normal Screen");
resetButton.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
shell.setFullScreenMode(false);
resetButton.setVisible(false);
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
// Create SortedList and add items
SortedList sortedList = new SortedList(
shell,
SWT.MULTI|SWT.V_SCROLL|SWT.BORDER,
SortedList.FILTER);
sortedList.add("banana");
sortedList.add("123");
sortedList.add("12");
sortedList.add("happyhour");
sortedList.add("toobad");
sortedList.add("youknowwhat");
sortedList.add("yes");
sortedList.add("886222333");
// Create ListView and add items with image set
Image[] image = new Image[4];
image[0] = new Image(
Display.getDefault(),
MobileExtensionSample.class.getResource\
AsStream("/icons/sample.gif"));
image[1] = new Image(
Display.getDefault(),
MobileExtensionSample.class.getResource\
AsStream("/icons/sample.gif"));
image[2] = new Image(
Display.getDefault(),
MobileExtensionSample.class.getResource\
AsStream("/icons/sample.gif"));
image[3] = new Image(
Display.getDefault(),
MobileExtensionSample.class.getResource\
AsStream("/icons/sample.gif"));
final ListView lv = new ListView(shell, SWT.MULTI|SWT.BORDER);
for (int i=0; i<20; i++) {
lv.add("item"+i, image[i % 4]);
}
//Create a Command for setting low density
Command lowCommand = new Command(lv, Command.SELECT, 0);
lowCommand.setText("LOW");
lowCommand.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
lv.setLayoutDensity(ListView.LOW);
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
//Create a Command for setting high density
Command midCommand = new Command(lv, Command.SELECT, 0);
midCommand.setText("MEDIUM");
midCommand.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
lv.setLayoutDensity(ListView.MEDIUM);
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
FormLayout layout = new FormLayout();
layout.spacing = 2;
layout.marginHeight = layout.marginHeight = 2;
shell.setLayout(layout);
FormData sortedListData = new FormData();
sortedListData.top = new FormAttachment(0);
sortedListData.left = new FormAttachment(0);
sortedListData.right = new FormAttachment(100);
sortedListData.height = 120;
sortedList.setLayoutData(sortedListData);
FormData lvData = new FormData();
lvData.top = new FormAttachment(sortedList);
lvData.right = new FormAttachment(100);
lvData.left = new FormAttachment(0);
lvData.height = 130;
lv.setLayoutData(lvData);
FormData resetData = new FormData();
resetData.top = new FormAttachment(lv);
resetData.left = new FormAttachment(0);
resetButton.setLayoutData(resetData);
resetButton.setVisible(false);
shell.setSize(240,320);
shell.setText("Mobile Example");
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
}
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
eJFace 中可用的查看器类型有:CheckBoxTableViewer
CheckBoxTreeViewer
ComboViewer
ListViewer
TableViewer
TreeViewer
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
eWorkbench 应用程序开发
步骤 1:定义视图org.eclipse.ui.part.ViewPart
。正常视图是必需的,其他两个视图是可选的。
清单 4. 示例视图
<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee"><tr><td>
</td></tr></table>
public class DefaultView extends ViewPart {
public void createPartControl(Composite parent) {
//create a composite with fill layout to host a label
Composite composite = new Composite(parent, SWT.NONE);
composite.setLayout(new FillLayout());
// create a label
Label label = new Label(composite,SWT.CENTER);
label.setText("Hello eWorkbench!"); }
public void setFocus() {}
}
清单 5. plugin.xml
<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee"><tr><td>
</td></tr></table>
清单 6. plugin.xml
<table border="1" cellspacing="0" cellpadding="5" width="100%" bgcolor="#eeeeee"><tr><td>
</td></tr></table>
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
eUpdate 为需要包含更新管理功能的插件提供逻辑和用户界面。可以在这些插件的帮助下,或者通过使用 eUpdate 工作台应用程序提供对更新相关信息进行配置的完整 GUI,编写自己的更新功能。
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
获得产品和技术
讨论
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
<table border="0" cellspacing="0" cellpadding="0" width="100%"><tr><td colspan="3"></td></tr><tr valign="top" align="left"><td></td><td></td><td width="100%">
<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td>
</td></tr></table><table align="right" cellpadding="0" cellspacing="0" class="no-print"><tr align="right"><td>
<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="middle">
</td><td align="right" valign="top"></td></tr></table></td></tr></table>
↑返回目录
前一篇: 利用 WebSphere Studio 和 Eclipse 的集成 SCM 提高开发人员的生产力
后一篇: 使用 Update Manager 更新 RCP 应用程序