用 eJFace 开发嵌入式应用程序
2009-12-19 00:00:00 来源:WEB开发网可以毫无顾虑地说,在未来几年中,对移动设备应用程序的需求将越来越多。现在是学习 eJFace 的好时机,eJFace 是开放标准的嵌入式 JFace 库,它是构建嵌入式应用程序的一项新技术。嵌入式 JFace(Embedded JFace,eJFace)是嵌入式富客户端平台(embedded Rich Client Platform,eRCP)的组件,它为开发人员提供了一个嵌入式环境,用于组合嵌入式应用程序的用户界面 (UI)。
eJFace 包含一些库,使用这些库可以构建应用程序而无需进行复杂的 eSWT 编程。它将提供强大的 API 并引入 Model-View-Controller (MVC) 架构,用于轻松地实现和维护嵌入式应用程序。在本文中,我们将说明如何用 eJFace 开发应用程序,并比较 eJFace 与 JFace。本文将帮助熟悉 JFace 的开发人员了解 eJFace 与 JFace 之间的差异,并减少开发 eJFace 应用程序所需的时间。
您将学习以下内容:
eJFace 库的结构、eJFace 库的 API 及其用法
JFace 与 eJFace 之间的差异
如何在 eRCP 环境下开发 eJFace、eSWT 和 eWorkbench 应用程序
如何向应用程序中添加 eJFace 功能
概览
我们先简要回答一下开发人员最初看到 eJFace 时会问到的三大问题。
1. eJFace 是什么?
eJFace 专门用于手持设备并且是桌面型 JFace 库的纯子集。
扩展 eSWT 并与之进行互操作的不依赖于平台的用户界面 API。
集成了一些 eSWT 小部件以提供许多有用功能,例如基于 MVC 的查看器,它可用于减少开发和维护工作。
排除 JFace 库中体积庞大、在手持设备上没有优势的部分。
2. eJFace 的用途是什么?
eJFace 库将提供对于嵌入式设备有用的高级 UI 功能。
创建与 eWorkbench 集成的 eRCP 应用程序。
提供了一组类,这组类用于扩展 eSWT 以使 eRCP 应用程序可以与 eRCP 工作台集成并提供更复杂的小部件(例如面向 MVC 的查看器)。
3. eJFace 的特性是什么?
eSWT 与 eJFace 之间的关系就像 SWT 与 JFace 之间的关系一样。
eJFace 依赖于 eSWT 的 Core 和 Expanded 部分以及 Java 2, Micro Edition (J2ME) 连接设备配置(Connected Device Configuration,CDC)的配置文件。
它在查看器中把 eSWT 小部件打包到 MVC 范例的上下文中。它将隐藏许多实现细节并减少代码行数。
它构建于 eSWT 之上,并且无需使用附加本地库就可以运行。
它将提供一个允许高效处理资源以节约内存并提高性能的资源处理类。
eJFace 包及详细信息
表 1. eJFace 中受支持的包
包 | |
org.eclipse.jface.action | 支持共享 UI 资源,例如菜单、工具栏和状态行 |
org.eclipse.jface.operation | JFace 支持长期运行的操作 |
org.eclipse.jface.preference | 首选项框架 |
org.eclipse.jface.resource | 支持管理资源(例如 SWT 字体和图像) |
org.eclipse.jface.util | 构建 JFace 中随处使用的块(包括属性更改事件、侦听程序列表实现和运行时检查的断言) |
org.eclipse.jface.viewers | 查看器框架,这些查看器都是用于 SWT 小部件、基于模型的内容适配器 |
正如前面提到的,eJFace 将删除 JFace 的大量包和库,这些包和库都是面向桌面的并且不适用于手持设备。鉴于要求所使用的包和库占用较少内存并且为了降低实现复杂度,eJFace 提供了上面所示的包。要获得关于每个包的 API 的详细信息,请参考 eJFace Java 文档。
下面是表 1 中提到的包摘要。
org.eclipse.jface.action org.eclipse.jface.action 包用于通过响应用户操作来与用户进行互动。org.eclipse.jface.action 包仅支持向状态行中添加条目。但是,建议将 Action 包与 eSWT 命令小部件结合使用,因为命令小部件更易于使用。选择在附带的小部件获得焦点时显示的动态菜单。有关更多信息,请参阅样例应用程序中提供的示例命令小部件。org.eclipse.jface.operation eJface 删除了 JFace org.eclipse.jface.operation 包中除了 IRunnableWithProgress 接口以外的几乎所有功能。IRunnableWithProgress 接口适于由执行长期运行的操作的类来实现。长期运行的操作通常是由显示进度指示器以及 Cancel 按钮或进度条的模式对话框显示的。org.eclipse.jface.preference org.eclipse.jface.preference 只提供 PreferencePage 和 PreferenceStore 库。PreferencePage 是用于显示消息或请求获得有限信息的临时对话框的一次性使用资源。PreferencePage 将阻止运行其他 eRCP 应用程序,直至 PreferencePage 被关闭,这将确保在执行主程序之前先收集信息。PreferenceStore 用于保存应用程序的信息。PreferenceStore 将生成一个属性文件以帮助应用程序存储一些有用信息。PreferencePage 和 PreferenceStore 通常用于保存从用户输入中收集到的用久信息。PreferencePage 样例应用程序显示如何实现提示以收集用户信息和存储内容。org.eclipse.jface.resource 顾名思义,org.eclipse.jface.resource 包将管理资源,例如图像、颜色、和字体信息。它使您可以轻松地找到特定资源。另外:
ImageRegistry 和 ImageDescriptor 库用于维护符号颜色名称与 SWT 颜色之间的映射。受支持的图像格式依赖于平台。
JFaceColors 用于获得并存储设备的默认颜色。
FontRegistry 和 FontDescriptor 用于维护符号字体名称与 SWT 字体之间的映射。
CompositeImageDescriptor 是图像描述符的抽象类,可以通过其他图像合成一张图像以模拟自定义图形的效果。
JFaceResource 是用于访问特定于 eJFace 资源的实用程序方法。
StringConverter 将轻松地在各种数据类型与字符串之间进行转换。
org.eclipse.jface.util org.eclipse.jface.util 将提供增强 eSWT 应用(包括属性更改事件、事件侦听程序收集机制和运行时断言检查)的有用方法。org.eclipse.jface.viewers org.eclipse.jface.viewers 只包括 TreeViewer 和 TableViewer。这些查看器是基于 MVC 架构的,用于把内部功能与界面外观分隔开来。这将使您可以轻松地维护和扩展 eJFace 查看器。另外:
TreeViewer 是由显示用户展开和折叠节点和子节点的层次结构数据的 eSWT 树型小部件来实现的。
在构建 TreeViewer 之后,您必须通过实现 ITreeContentProvider 接口来确定 TreeViewer 的内容。
通过实现 ILabelProvider 接口来确定显示内容的方法。
通过使用指定内容和标签提供程序将其传递给数据的根节点。
TableViewer 是由用于显示列数据与行数据的 eSWT 表小部件实现的。Table 和 TableItem 可用于完成 TableViewer 的功能。
类似于 TreeViewer,您将首先创建 TableViewer,然后相应地设定内容提供程序。
设定标签提供程序。
设定输入。
下载 中的 eJFace org.eclipse.jface.viewers 演示应用程序将显示如何实现 TreeViewer 和 TableViewer。
eJFace 与 JFace 之间的差异
正如前面提到的,eJFace 是 JFace 的严格子集。将删除或减少相当一部分不太可能用在嵌入式设备上的库。表 2 汇总了 eJFace 与 JFace 之间的主要差异。
表 2. eJFace 与 JFace 的差异
eJFace 与 JFace 比较 | |
从 JFace 中删除的包 | org.eclipse.jface.dialogs org.eclipse.jface.operation(eJFace 将只提供 IRunnableWithProgress 接口) org.eclipse.jface.window org.eclipse.jface.wizard |
JFace 中减少的包 | org.eclipse.jface.action org.eclipse.jface.preference(eJFace 将只提供 PreferencePage 类) org.eclipse.jface.viewers(eJFace 将只提供 TreeViewer 和 TableViewer) |
未更改的包 | org.eclipse.jface.resource org.eclipse.jface.util |
您可能想知道为什么把 jface.wizard、jface.dialogs 和 jface.window 从 JFace 中删除。原因有两个:首先,现有对话框、向导和窗口代码都是面向桌面的,并且需要进行大量的修改工作才能由移动设备使用。例如,手机中的对话框通常不应使用按钮,因为手机可能没有光标和鼠标。其次,所选包都是应用程序可以轻松实现的便利函数,而不是复杂代码或通用代码。
您可能还希望了解 eJFace 代码不在 eSWT Mobile Extensions 中使用命令类的原因。我们不希望让 eJFace 依赖于 Mobile Extensions,因为它应该是 eRCP 中的可选组件。此外,Mobile Extensions 将提供 QueryDialog 和 TimedMessageBox,用于把一些 JFace 对话框替代为相应的移动版本。
对 org.eclipse.jface.action 的更改要求提供说明。JFace 仅支持向状态行中添加条目。由于 eWorkbench 不提供常见的菜单栏函数,因此将从 eJFace 中删除大多数操作类。不过,将在 eSWT 的 Mobile Extensions 中把操作条目替换为命令类。
eJFace org.eclipse.jface.viewers 演示应用程序
eJFace 只提供 TreeViewer 和 TableViewer。
TreeViewer
要设计 TreeViewer 演示应用程序,您必须创建节点类作为数据模型。在这里,我们将创建两个名为 NBATeamNode 和 NBAPlayer 的节点类。接下来,您必须定义节点之间的关系。例如,NBATeamNode 可以添加其他 NBATeamNode 或 NBAPlayer 实例。您必须在 NBATeamNode 中定义两个单独的 ArrayLists 才能添加。
清单 1. 定义节点类及其父子节点关系public class NBATeamNode {
private String name;
private ArrayList teams = new ArrayList();
private ArrayList players = new ArrayList();
private NBATeamNode parent;
public NBATeamNode(String n){
name = n;
}
protected Object getParent(){
return parent;
}
public NBATeamNode addTeam(NBATeamNode child){
teams.add(child);
child.parent = this;
return this;
}
public NBATeamNode addPlayer(NBAPlayer child){
players.add(child);
child.parent = this;
return this;
}
public ArrayList getteams(){
return teams;
}
public ArrayList getplayers(){
return players;
}
public String toString(){
return name;
}
public class NBAPlayer {
private String name;
NBATeamNode parent;
public NBAPlayer(String n){
name = n;
}
protected Object getParent(){
return parent;
}
public String toString(){
return name;
}
在扩展 org.eclipse.ercp.eworkbench.applications 之后,我们将创建 TreeViewer 实例并与生成的 SampleView 类的 createPartControl 方法中的当前复合内容关联起来。然后设定此树的期望布局并向此 TreeViewer 中添加树内容提供程序和树标签提供程序实例。内容提供程序将提供所有树的父子节点关系,而标签提供程序将提供每个元素所表示的图像和文本。最后,为这个 TreeViewer 给定一个输入节点。记住,此输入节点应当是数据模型的根节点。例如,我们将先创建根节点并向其中添加三个 NBATeamNode 作为另一个球队名称。然后,我们将使用变量 NBAPlayer 将五个首发上场的 NBA 球员添加到每个球队中。正如您可以看到的那样,我们把名为 “root” 的根 NBATeamNode 输入到 TreeViewer 中。
清单 2. SampleView 类public void createPartControl(Composite parent){
composite= new Composite(parent,SWT.NONE);
composite.setLayout(new GridLayout(1,false));
treeviewer = new TreeViewer(composite);
treeviewer.getTree().setLayoutData(new GridData(GridData.FILL_BOTH));
treeviewer.setContentProvider(new SampleTreeContentProvider());
treeviewer.setLabelProvider(new SampleTreeLabelProvider());
treeviewer.setInput(getInput());
treeviewer.expandAll();
}
private NBATeamNode getInput(){
NBATeamNode root = new NBATeamNode("root");
NBATeamNode team1= new NBATeamNode("Houston Rockets");
NBATeamNode team2= new NBATeamNode("LA Lakers");
...
root.addTeam(team1);
root.addTeam(team2);
...
team1.addPlayer(new NBAPlayer("Yao Ming"));
team1.addPlayer(new NBAPlayer("Tracy McGrady"));
...
return root;
}
树内容提供程序必须实现 ITreeContentProvider。使用 getParent 和 getChildren 方法定义此树的父子节点关系。最后,使用 getElements 方法获得每个元素的子元素。
清单 3. TreeViewerContentProviderpublic class SampleTreeContentProvider implements ITreeContentProvider {
//other methods are not mentioned here are unchanged
public Object[] getChildren(Object arg0) {
if(arg0 instanceof NBATeamNode) {
NBATeamNode node = (NBATeamNode)arg0;
return concat(node.getteams().toArray(),node.getplayers().toArray());
}
return EMPTY_ARRAY;
}
protected Object[] concat(Object[] object, Object[] more) {
Object[] both = new Object[object.length + more.length];
System.arraycopy(object, 0, both, 0, object.length);
System.arraycopy(more, 0, both, object.length, more.length);
return both;
}
public Object getParent(Object arg0) {
return ((NBATeamNode) arg0).getParent();
}
public Object[] getElements(Object arg0) {
return getChildren(arg0);
}
树标签提供程序必须实现 ILabelProvider。正如您可以看到的那样,我们将使用 getImage 和 getText 方法定义每个节点所表示的图像和文本。
清单 4. TreeViewerLabelProviderpublic class SampleTreeLabelProvider implements ILabelProvider {
//other methods are not mentioned here are unchanged
private ArrayList listeners;
private Image Team, Player;
public SampleTreeLabelProvider(){
listeners = new ArrayList();
Team = new Image(null, getClass().getResourceAsStream("/res/file.png"));
Player= new Image(null, getClass().getResourceAsStream("/res/folder.png"));
}
public Image getImage(Object arg0) {
if(arg0 instanceof NBATeamNode){
return Team;
}else{
return Player;
}
}
public String getText(Object arg0) {
if(arg0 instanceof NBATeamNode) {
return ((NBATeamNode)arg0).toString();
}else{
return ((NBAPlayer)arg0).toString();
}
}
public void dispose() {
if(Team != null) Team .dispose();
if(Player != null) Player.dispose();
}
}
当您把此演示应用程序部署到设备上的 eWorkbench 中后,您将看到图标显示在名为 Test TreeViewer Sample 的应用程序列表中。在命令窗口中单击 Open 来启动它。那时,您将找到我们创建的树。您可以扩展每个球队并可以在球队名册中看到相应的球员。
图 1. 设备上 eWorkbench 中的 TreeViewer 演示应用程序
查看原图(大图)
TableViewer
要设计 TableViewer 演示应用程序,您必须创建数据模型类。在这里,将创建 Book.java。如您所见,有五个属性需要输出到表列中。因此,您必须为每个属性使用 getter-setter 方法以供进一步使用。
清单 5. 定义数据模型类public class Book {
String name;
String isbn;
String publisheddate;
String price;
String available;
public String getAvailable() {
return available;
}
public void setAvailable(String available) {
this.available = available;
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public String getPublisheddate() {
return publisheddate;
}
public void setPublisheddate(String publisheddate) {
this.publisheddate = publisheddate;
}
}
在扩展 org.eclipse.ercp.eworkbench.applications 之后,我们将创建 TableViewer 实例并将其与 SampleView 类中的当前合成的 createPartControl 方法关联起来。然后设定期望的布局。但是在向此表查看器中添加内容提供程序和标签提供程序实例之前,我们必须先创建表。表包括适当的列数和相应名称。打包每个列并使其显示在表中。最后,设定 table content provider 和 table label provider 并提供此 TableViewer 输入(换言之,为它提供数据)。记住,此输入必须是数据模型的 ArrayList。例如,先创建 ArrayList 并向其中添加三个书实例。将根据内容提供程序类和标签提供程序类设定表中字段的值。
清单 6. SampleView 类public void createPartControl(Composite parent) {
composite= new Composite(parent,SWT.NONE);
composite.setLayout(new GridLayout(1,false));
tableviewer = new TableViewer(composite);
Table table = tableviewer.getTable();
table.setLayoutData(new GridData(GridData.FILL_BOTH));
column0 = new TableColumn(table,SWT.LEFT,0);
column0.setText("Books Name");
column1 = new TableColumn(table,SWT.LEFT,1);
column1.setText("ISBN");
column2 = new TableColumn(table,SWT.LEFT,2);
column2.setText("Published Date");
column3 = new TableColumn(table,SWT.LEFT,3);
column3.setText("Price");
column4 = new TableColumn(table,SWT.LEFT,4);
column4.setText("Available Now?");
for(int i =0, n=table.getColumnCount();i<n;i++){
table.getColumn(i).pack();
}
table.setHeaderVisible(true);
table.setLinesVisible(true);
tableviewer.setContentProvider(new SampleTableContentProvider());
tableviewer.setLabelProvider( new SampleTableLabelProvider());
tableviewer.setInput(getInput());
}
private ArrayList getInput() {
Book b1 = new Book();
Book b2 = new Book();
Book b3 = new Book();
b1.setName("Red Book");
b1.setIsbn("U2w3e4r5t6y");
b1.setPublisheddate("1980-08-28");
b1.setPrice("$1000");
b1.setAvailable("Yes");
b2.setName("Blue Book");
b2.setIsbn("U1q2w3e4r");
...
return Books;
}
TableViewerContentProvider 必须实现 IStructuredContentProvider 接口。TableViewerContentProvider 将定义此表的显示关系。正如您可以在此类中看到的那样,我们将使用 getElements 方法获得一个特定数组的每条数据,该数组可以表示书名,也可以表示价格。
清单 7. TableViewerContentProviderpublic class SampleTableContentProvider implements IStructuredContentProvider {
//other methods are not mentioned here are unchanged
public Object[] getElements(Object arg0) {
return ((ArrayList)arg0).toArray();
}
}
TableViewerLabelProvider 必须实现 ITableLabelProvider 接口。TableViewerLabelProvider 将定义此表中每列的文本或图像。我们可以使用 getColumnText 方法获得每个元素的文本(在这里,我们并未实现 getColumnImage 方法)。
清单 8. TableViewerLabelProviderpublic class SampleTableLabelProvider implements ITableLabelProvider {
//other methods are not mentioned here are unchanged
public Image getColumnImage(Object arg0, int arg1) {
return null;
}
public String getColumnText(Object arg0, int arg1) {
String result = "";
Book book = (Book) arg0;
switch(arg1){
case 0:
result = book.getName();
break;
case 1:
result = book.getIsbn();
break;
case 2:
result = book.getPublisheddate();
break;
case 3:
result = book.getPrice();
break;
case 4:
result = book.getAvailable();
break;
}
return result;
}
public boolean isLabelProperty(Object arg0, String arg1) {
return false;
}
}
当您把此演示应用程序部署到 eWorkbench 设备中后,您将看到图标显示在名为 Test TableViewer Sample 的应用程序列表中。在命令窗口中单击 Open 以启动它。您将找到我们创建的表。
图 2. 设备上的 eWorkbench 中的 TableViewer 演示应用程序
查看原图(大图)
eJFace org.eclipse.jface.preference 演示应用程序
PreferencePage
eJFace 只提供 PreferencePage 来存储您所需的必备首选项数据,例如服务器信息、用户名和密码。而且,它仅在目标为 eWorkbench 时才能运行。在图 3 中,我们将展示如何开发一个简单的首选项应用程序,包括 OK、Cancel 和 Restore Default 按钮。
清单 9. 添加到 plugin.xml<extension point="org.eclipse.ui.preferencePages">
<page
class="preferencesample.PrefPageOne"
id="preferenceSample.page1"
name="Server authentication"/>
</extension>
您的首选项页面类必须扩展 PreferencePage 并实现 IWorkbenchPreferencePage 以使您的首选项页面显示在 eWorkbench 中。首先,声明必需的变量,包括 String、Text、Label、Button 和 PreferenceStore。PreferenceStore 将存储您键入的名称-值对。createContents 方法用于显示用户的首选项。
首先,先创建一个合成的首选项页面并用 GridLayout 设定布局。其次,用一个惟一名称创建 PreferenceStore 并通过这个 PreferenceStore 装入数据。再次,创建三个允许用户键入所需值的文本字段。值包括服务器地址、用户名和密码。使用 SetDefaultValue() 来设定这些字段的默认值。当用户打开首选项页面时,他们将看到这些默认值。
使用 performDefaults 将重置默认值。使用 performOK 将在您单击 OK 时保存键入的值。使用 performCancel 将在您单击 Cancel 时不保存任何更改退出此首选项页面。当首选项页面实现 IWorkbenchPreferencePage 时,init(IWorkbench arg0) 是必须实现的必备方法。
清单 10. 首选项页面样例代码public class PrefPageOne extends PreferencePage implements IWorkbenchPreferencePage{
private static final String SERVERADDR = "SERVERADDR";
private static final String USERNAME = "USERNAME";
private static final String USERPASSWORD = "USERPASSWORD";
private Text fieldOne;
private Text fieldTwo;
private Text fieldThree;
Label label1, label2, label3;
Composite composite;
Button defaultbutton;
PreferenceStore preferenceStore;
protected Control createContents(Composite parent){
composite = new Composite(parent, SWT.NONE);
composite.setLayout(new GridLayout(2,false));
preferenceStore = new PreferenceStore("com.ibm.test.ejface.preference");
try {
preferenceStore.load();
}catch (IOException e) {}
label1 = new Label(composite, SWT.LEFT);
label1.setText("Server address:");
label1.setground(new Color(composite.getDisplay(),0x66, 0xCC, 0xFF));
fieldOne = new Text(composite, SWT.SINGLE | SWT.BORDER);
fieldOne.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
label2 = new Label(composite, SWT.LEFT);
label2.setText("Username:");
fieldTwo = new Text(composite, SWT.SINGLE | SWT.BORDER);
fieldTwo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
label3 = new Label(composite, SWT.LEFT);
label3.setText("Password:");
fieldThree = new Text(composite, SWT.SINGLE | SWT.BORDER | SWT.PASSWORD);
fieldThree.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
SetDefaultValue();
fieldOne.setText(preferenceStore.getString(SERVERADDR));
fieldTwo.setText(preferenceStore.getString(USERNAME));
fieldThree.setText(preferenceStore.getString(USERPASSWORD));
defaultbutton = new Button(composite,SWT.PUSH | SWT.LEFT);
defaultbutton.setText("Restore to Default value");
defaultbutton.addSelectionListener(new SelectionListener(){
public void widgetSelected(SelectionEvent e) {
performDefaults();
}
public void widgetDefaultSelected(SelectionEvent e) {
}});
return composite;
}
protected void performDefaults(){
fieldOne .setText(preferenceStore.getDefaultString(SERVERADDR));
fieldTwo .setText(preferenceStore.getDefaultString(USERNAME));
fieldThree.setText(preferenceStore.getDefaultString(USERPASSWORD));
}
public boolean performOk(){
if(fieldOne != null && fieldOne .getCharCount() != 0)
preferenceStore.setValue(SERVERADDR, fieldOne .getText());
if(fieldTwo != null && fieldTwo .getCharCount() != 0)
preferenceStore.setValue(USERNAME, fieldTwo .getText());
if(fieldThree != null && fieldThree.getCharCount() != 0)
preferenceStore.setValue(USERPASSWORD, fieldThree.getText());
try{
preferenceStore.save();
} catch (IOException e) {
return false;
}
return true;
}
private void SetDefaultValue() {
if (fieldOne != null && fieldOne.getCharCount() == 0) {
preferenceStore.setDefault(SERVERADDR, "www.ibm.com");
}
if (fieldTwo != null && fieldTwo.getCharCount() == 0) {
preferenceStore.setDefault(USERNAME, "Administrator");
}
if (fieldThree != null && fieldThree.getCharCount()== 0) {
preferenceStore.setDefault(USERPASSWORD, "admin");
}
}
public boolean performCancel() {
composite.dispose();
this.dispose();
return true;
}
public void init(IWorkbench arg0) {
}
}
在把此演示应用程序部署到 eWorkbench 设备中后,您将看到图表显示在 Preference Demo Application 列表中。单击 OK 以保存输入内容,单击 Cancel 以退出首选项页面,或者单击 Restore 以将每个文本字段的值重设为默认值。
图 3. eWorkbench 设备中的首选项页面演示应用程序
查看原图(大图)
eJFace org.eclipse.jface.resource 演示应用程序
eJFace 只提供重要的 org.eclipse.jface.resource 包库。在演示应用程序中,我们将演示如何使用 ImageRegistry 和 fontRegistry 以高效地管理图像和字体对象。还引入了 JFaceColors 以帮助管理相应小部件的颜色。此外,我们将展示如何使用命令小部件以实现 org.eclipse.jface.action 功能。
清单 11 中列出了演示代码,这段代码将使用注册表把字体、颜色和图像设定到相应的小部件中。我们还将展示如何构造 eSWT 命令小部件。此外,它只在目标为 eWorkbench 中的应用程序时才运行。
ImageRegistry 用于存储和装入不同的图像。使用 put() 和 get() 方法,您可以轻松地把名称分配给图像和管理许多图像。FontRegistry 类似于 ImageRegistry 并用于存储和装入不同的 fontData。使用 put 和 get 方法,用户可以高效地管理字体。JFaceResources 可用于在整个程序中管理 ImageRegistry 和 FontRegistry。
JFaceColors 可以把特定颜色动态指派给小部件的前景和背景。StringConverter 将提供 Java 字符串处理功能。在此演示应用程序中,我们将使用它把字符串对象分割为 StringArray。
命令小部件是一个有用的 eSWT API。命令仅在附带的小部件获得焦点时显示。在本样例中,RecoverCommand 附带了合成对象。RecoverCommand 在合成对象获得焦点时显示。否则,RecoverCommand 将消失。我们将向 RecoverCommand 中添加 SelectionListener。当 RecoverCommand 被选中时,将调用 widgetSelected。
下面是设备上的资源演示样例。
清单 11. 资源样例代码//ImageRegistry demo
ImageRegistry ir = new ImageRegistry();
ir.put("img1",new Image(display,getClass().getResourceAsStream("/icons/ibm1.png")));
ir.put("img2",new Image(display,getClass().getResourceAsStream("/icons/ibm2.png")));
Label Imagelabel = new Label (composite, SWT.LEFT);
Imagelabel.setImage(ir.get("img1"));
//FontRegistry demo
FontRegistry fr = new FontRegistry(composite.getDisplay());
FontData[] fd = new FontData[2];
fd[0]= new FontData("Tacoma",20, SWT.NORMAL);
fd[1]= new FontData("Times New Roman",12, SWT.NORMAL);
fr.put("SysFont", fd);
Label Fontlabel = new Label (composite, SWT.LEFT);
Fontlabel.setText("FontRegistry");
Font normalfont = new Font(composite.getDisplay(),fr.getFontData("SysFont")[0]);
Fontlabel.setFont(normalfont);
JFaceResources.setFontRegistry(fr);
Font font = new Font(display, JFaceResources.getFontRegistry().getFontData
("SysFont")[1]);
//JFaceColors demo
Label JFaceColorslabel = new Label (composite, SWT.LEFT);
JFaceColorslabel.setText("JFaceColors");
JFaceColors.setColors(JFaceColorslabel, composite.getDisplay().getSystemColor
(SWT.COLOR_DARK_YELLOW), composite.getDisplay().getSystemColor(SWT.COLOR_BLUE));
String[] stringArray = StringConverter.asArray("eJface Developer Works");
Command RecoverCommand = new Command(composite, Command.OK, 0);
RecoverCommand.setText("Default Setting");
RecoverCommand.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
Imagelabel.setImage(ir.get("image1"));
Imagelabel.redraw();
Fontlabel.setFont(font);
Fontlabel.redraw();
stringButton.setText("eJface Developer Works");
}
public void widgetDefaultSelected(SelectionEvent e) {
}
});
图 4. eJFace 资源样例(更改前)
图 5. eJFace 资源样例(更改后)
eWorkbench 上的 eJFace 集成演示应用程序
现在将把上面所述的所有子函数集成到一个样例中。首先,创建一个可以根据选择显示 NBA 或 MLB 球员的 TreeViewer。其次,有一个根据您是位于 NBA 页面还是位于 MLB 页面显示默认值的首选项页面。再次,可以突出显示窗口中的一个球队或球员,然后在命令窗口中单击 2005~2006 record。设备将创建一个记录这条用 TableViewer 创建的记录的表。由于源代码全部显示在这里会显得太长,并且此整合样例中未添加任何新函数,因此您可以到 下载 中找到源代码进行进一步研究。图 6、图 7 和图 8 演示了设备上的整合。
图 6. eWorkbench 中所示的 eJFace 整合样例
图 7. NBA 首选项页面;默认值是 NBA 的首选项
图 8. 显示球员记录的表
结束语
本文演示了开发 eJFace 应用程序所需的步骤,比较了 JFace 与 eJFace,并且研究了 eJFace 开发背后的原因。在此过程中,回顾了 eJFace 库的结构、eJFace 库的 API 及其用法,了解了如何在 eRCP 环境内开发 eJFace、eSWT 和 eWorkbench 应用程序,并且向应用程序中添加了 eJFace 功能。
本文示例源代码或素材下载
- ››开发学院教你用SQL 语句最快速清空MySQL 数据表的...
- ››嵌入式实时程序设计中C/C++代码的优化
- ››开发一个自己的HTML在线编辑器(一)
- ››开发一个自己的HTML在线编辑器(二)
- ››开发者在App Store上赚的钱比在Android Market上多...
- ››开发者应深入学习的10个Android开源应用项目
- ››开发移动 Web Ajax 应用
- ››开发者眼中的iPhone与Android
- ››开发者或想使用的10个Android2.2新特性
- ››开发实例:Android 身高计算器的实现
- ››开发 Derby 的表功能
- ››开发火爆 博看文思称 iPhone 可作\血压计\
赞助商链接