IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  Lotus  >

在 IBM Lotus Notes V8 客户机中集成复合应用程序和活动

developerWorks
文档选项

未显示需要 JavaScript 的文档选项

讨论

样例代码


级别: 中级

Michael Crawford (michael.crawford@ie.ibm.com), 软件开发人员, IBM

2007 年 9 月 03 日

学习如何创建 Eclipse 视图组件以及如何将其添加到 IBM Lotus Notes V8 的新复合应用程序中;组件将使用 Activities API 来创建、读取、更新并删除 Activities 服务器上的活动。

随着新 IBM Lotus Notes V8 客户机的发布,复合应用程序也得到了发展。使用复合应用程序,可以对相似的组件进行合并以提供完整的应用程序。可以通过不同来源获取组件,包括 IBM Lotus Domino 数据库、Eclipse 视图和 JSR 168 portlet。

活动提供了一种组织、共享和重用任务的方法。这样,可以将相关文档存储在某个活动中,有关人员(如项目管理活动的团队成员)可以对它进行访问。

在本文中,将学习如何创建可以包含在复合应用程序中的基于 Eclipse 的组件。该组件使用 Activities API 查询 Activities 服务器,并且允许您在返回的结果上执行多种函数。

先决条件

若要使用 Activities API,必须确保在安装 Lotus Notes V8 时选中了 Activities 特性。选择 Activities 选项,如图 1 所示。

还需要选择 Composite Application Editor,将使用它来构造复合应用程序。如果在安装 Lotus Notes V8 时没有选择上述功能,则返回 Install Wizard,然后添加上述功能。


图 1. 安装向导
安装向导




回页首


在 Eclipse 中配置项目

分享这篇文章……

digg 提交到 digg
del.icio.us 发布到 del.icio.us
Slashdot 提交到 Slashdot!

项目是包含在插件项目中的 Eclipse 视图。可以在 Eclipse 中创建新的 Plug-in Project,选择 File – New – Other,然后从 Plug-in Development 目录中选择 Plug-in Project。输入 Activities 作为项目名称,单击 Next,然后单击 Finish。

Eclipse IDE 将创建插件,对插件进行配置,使其包含一个扩展 org.eclipse.ui.views 扩展点的视图。若要获得有关 Eclipse 扩展的更多信息,请参阅 Eclipse Web 站点

继续进行操作之前,必须确保将项目的 Compiler Compliance Level 设置为 Java 1.4。若要确认该设置,选择 Window – Preferences 打开 Preferences 对话框,然后导航到 Java – Compiler 窗口。

若要创建扩展,右键单击 META-INF 文件夹中的 MANIFEST.MF 文件,然后选择 Open With – Plug-in Manifest Handler。接着选择 Extensions 附签并单击 Add 按钮。在打开的窗口中,选择 Extension Points 附签中的 org.eclipse.ui.views,然后单击 Finish。右键单击所创建的扩展,然后选择 New - View。ID Activities.view1 将添加一个新的视图扩展。将 allowMultiple 选项设置为 true,如图 2 所示。保存文件。


图 2. 扩展
扩展

在图 2 中可以看到,会自动使用文本 activities.ViewPart1 填充与扩展相对应的类位置。现在必须创建该文件。在 Package Explorer 中扩展 src 文件夹,然后右键单击活动包并选择 New – Class。输入 ViewPart1 作为类名,然后选择浏览 Superclass,在所出现的对话框中输入 ViewPart。单击 Finish。

已成功创建一个包含 Eclipse 视图的插件,该视图扩展对扩展点 org.eclipse.ui.views 进行扩展。若要访问 Activities API,首先必须包含 com.ibm.openactivities.client.common.service 插件作为项目的依赖关系。还需要 org.apache.commons.httpclient 和 com.ibm.rcp.accounts 插件。

若要包含这些依赖关系,首先将 Target Platform 更改为指向 Lotus Notes V8 安装目录。选择 Window – Preferences,然后从 Plug-in Development 附签选择 Target Platform。将位置更改为指向 Notes 安装中的 Eclipse 目录,默认情况下为 C:\Program Files\IBM\Lotus\notes\framework\eclipse。单击 Reload 按钮。

使用 Plug-in Manifest Handler 重新打开 MANIFEST.MF,然后选择 Dependencies 附签。单击 Add 按钮并搜索插件。现在 dependencies 附签如图 3 所示。


图 3. Dependencies
Dependencies




回页首


Activities 服务器证书

Lotus Notes V8 客户机的一个新特性是 Sidebar,允许您使用某些特性,如 IBM Lotus Sametime、RSS 提要、每日一瞥(day-at-a-glance)功能和 Activities。若要使用 Activities 窗格,则为 Activities 服务器指定证书,可以选择 File – Preferences 进行访问,如图 4 所示。


图 4. Preferences 对话框
Preferences 对话框

假定用户已经输入 Activities 服务器的证书,可以使用 Lotus Notes 中实现的 Accounts Manager 访问证书。然后在复合应用程序中使用该信息。

首先,添加新的类变量存储那些需要连接到服务器的值。然后,在 ViewPart1 类中创建一个新方法 initialize(),将使用 Accounts Manager 填充值,如清单 1 所示。


清单 1. initialize() 方法


package activities;

import org.eclipse.swt.widgets.Composite;
import org.eclipse.ui.part.ViewPart;
import com.ibm.rcp.accounts.Account;
import com.ibm.rcp.accounts.AccountsManager;
import com.ibm.rcp.accounts.AccountsManagerFactory;

public class ViewPart1 extends ViewPart {
	
	private String _activitiesServer;
	private int _port;
	private String _protocol;
	private String _email;
	private String _password;
	
	private void initialize(){
	  AccountsManager manager = AccountsManagerFactory.getAccountsManager();
	  Account account = manager.getAccountByName("Activities");
	  String server = account.getProperty("server");
	  String [] temp = server.split("://");    
  _protocol = temp[0];
  _activitiesServer = temp[1];
	  _port = Integer.valueOf(account.getProperty("portnumber")).intValue();
	  _email = account.getProperty("username");
	  _password = account.getLoginContext().getPassword();
	}

	public void createPartControl(Composite parent) {
		// TODO Auto-generated method stub
	}

	public void setFocus() {
		// TODO Auto-generated method stub
	}
}





回页首


连接到 Activities 服务器

既然已经访问了用户的 Activity 服务器证书,现在可以创建 OpenActivitiesClient 实现,用于查询服务器。

添加另一个类变量来表示 OpenActivitiesClient 对象,并创建一个新方法,如清单 2 所示。


清单 2. createActivitesClient() 方法

	
	private OpenActivitiesClient _activitiesClient;
	
	private void createActivitiesClient(){
	  HttpClient myClient = new HttpClient();
	  myClient.getHostConfiguration().setHost(_activitiesServer, _port, _protocol);
	  Credentials defaultcreds = new UsernamePasswordCredentials(_email, 
		_password);
	  AuthScope as = new AuthScope(null,-1,null);
	  myClient.getState().setCredentials(as,defaultcreds);
	  _activitiesClient = OpenActivitiesClientFactory.INSTANCE.create(myClient);
	}

请确保使用 org.apache.commons.httpclient.HttpClient 和 org.apache.commons.httpclient.Credentials。

该方法将创建 HttpClient,并使用描述服务器的 HTTP 连接所必需的所有变量来填充 HostConfiguration 对象。接着可以将该 HttpClient 传递到返回 OpenActivitiesClient 对象的单个 OpenActivitiesClientFactory 实例。





回页首


使用作业(job)获得更好的性能

新的 Lotus Notes 客户机旨在确保获得尽可能快的用户响应时间。若要确保最优响应时间,则不能编写在一个 UI 线程中尝试访问网络的代码。因此,您必须编写在新线程内部与 Activities 服务器进行交互的代码。

Eclipse 通过 Job Manager 简化了该过程,为调度、查询和维护 Job 和锁提供了方便。Job 是一个可运行的任务单元(即线程)。

在以下章节中,将创建自己的 Job 和 UIJob 对象,分别处理 Activities 服务器调用或刷新 UI。





回页首


查询 Activities 服务器

若要确定希望从 Activities 服务器返回的信息,则创建 NodeRetrievalOptions 对象,它可以使用多种方法指定包含在查询中的值。其中一些方法如表 1 所示。


表 1. NodeRetrievalOptions 方法
方法描述
setTags(String []) 搜索那些包含 String 数组中所含标记(活动的描述性术语)的活动。
setMemberIds(String [])传递电子邮件地址数据数组,搜索那些涉及所列人员的活动。
setIncludeDeleted(int)标记是否在结果中包括已删除活动。1 表示包括,0 表示不包括。
setAssignedTo(String [])传递电子邮件地址数据数组,搜索那些指定给所列人员的活动。
setCaseSensitive(boolean)设置搜索条件是否区分大小写。
setIncludeTunedOut(int)标记是否包含已关闭的活动。已关闭的活动不会在 Activity Dashboard 中出现。

针对第一个查询的目的,创建的 NodeRetrievalOptions 对象将使用来自 AccountsManager 的电子邮件地址作为要搜索的成员电子邮件地址。这样将返回指定给用户的所有活动作为 java.util.List 中的对象。首先,为该列表创建一个新的类变量,可以从其他方法中访问该变量:

private List _activitiesList = new ArrayList();

然后,创建清单 3 中的方法来执行查询。请注意,已经在 Job 中包含需要网络访问的代码。


清单 3. 创建 getAllActivities() 方法

	private void getAllActivities(){
	  Job myJob = new Job ("Job"){
		protected IStatus run(IProgressMonitor arg0) {
		  _activitiesList.clear();
		  NodeRetrievalOptions retrievalOptions = new NodeRetrievalOptions();
		  retrievalOptions.setAssignedTo(new String []{_email});
		  try {
			NodeCollection activities = 
_activitiesClient.getActivities(retrievalOptions);
			NodeSummary [] activityNodes = activities.getNodes();
			for (int i=0;i<activityNodes.length;i++){
			  _activitiesList.add(activityNodes[i]);
			}
		  }
  catch (OpenActivitiesException e) {
			e.printStackTrace();
		  };
		  updateUI();
		  return Status.OK_STATUS;
		}
	  };
	  myJob.schedule();
	}

从服务器返回的每个活动均由一个 NodeSummary 对象表示,从该对象可以得到所有相关信息,如活动名、描述、最后一次修改日期以及许可。





回页首


显示查询结果

在简单的 SWT (Standard Widget Toolkit) Table 中显示查询结果,将列出所有返回活动的名称和描述。首先,创建以下类变量来表示表及其列,以便从其他方法中进行访问:

private Table _activitiesTable;
TableColumn _nameCol;
TableColumn _descCol;

编辑 ViewPart1 类的 createPartControl() 方法,如清单 4 中所示。


清单 4. 编辑 createPartControl() 方法


	public void createPartControl(final Composite parent) {
	  initialize();
	  createActivitiesClient();

	  _activitiesTable = new Table(parent, SWT.NONE);
	  _activitiesTable.setHeaderVisible(true);

	  _nameCol = new TableColumn(_activitiesTable, SWT.NONE);
	  _nameCol.setText("Name");

	  _descCol = new TableColumn(_activitiesTable, SWT.NONE);
	  _descCol.setText("Description");

	  getAllActivities();
	}

下面实现清单 4 中引用的 updateUI() 方法。在 UIJob 中包含对表进行刷新的代码,如清单 5 所示。


清单 5. 实现 updateUI() 方法

	private void updateUI(){
	  UIJob myUIJob = new UIJob("UIJob"){
		public IStatus runInUIThread(IProgressMonitor arg0) {
		  _activitiesTable.removeAll();
		  for (int i=0;i<_activitiesList.size();i++){
			NodeSummary currentNodeSummary = 
(NodeSummary) _activitiesList.get(i);
			TableItem tableItem = new TableItem(_activitiesTable, SWT.NONE);
			tableItem.setData(currentNodeSummary);
			tableItem.setText(0, currentNodeSummary.getName());
			tableItem.setText(1, currentNodeSummary.getDescription());
		  }
		  _nameCol.pack();
		  _descCol.pack();
		  _activitiesTable.redraw();
		  return Status.OK_STATUS;
		}
	  };
	  myUIJob.schedule();
	}

对于用户来说,此时的插件没有任何实际功能 —— 除了在服务器上显示所有活动列表之外。在继续进行开发之前,最好检查一下所有操作是否正常进行。





回页首


向复合应用程序添加插件

要将插件添加到复合应用程序中,先将其添加到 Update Site。然后使用 Lotus Notes V8 中的 Composite Application Editor 将插件添加到应用程序。

选择 File – New – Other,再选择 Plug-in Development 文件夹中的 Feature Project 选项,然后单击 Next。输入 ActivitiesFeature 作为项目名,单击 Next,然后从列表中选择 Activities 插件,单击 Finish。按照以上步骤创建了一个新的 Update Site Project(在这里将选择更新站点选项,而不是特性),将项目命名为 ActivitiesUpdateSite,然后单击 Finish。

创建 Update Site 之后,使用 Site Manifest Editor 打开 site.xml 文件。在 Update Site Map 对话框中,单击 Add Feature 按钮并选择 ActivitiesFeature。单击 OK,然后保存文件。若要生成更新站点,则单击 Build All 按钮,如图 5 所示。


图 5. Update Site Map 对话框
Update Site Map 对话框

若要测试插件,则创建新的复合应用程序并添加视图作为组件。首先,启动 Lotus Notes V8 客户机,按 Ctrl+N 打开图 6 所示对话框。输入 Test 作为标题,确保已选中 Blank Composite Application 模板,然后单击 OK。


图 6. New Application 对话框
New Application 对话框

已创建一个新的复合应用程序。若要进行编辑,选择 Actions – Edit Application 来启动 Composite Application Editor。依次选择 Tools – Component Palette – Open 来查看组件面板。要向面板添加组件,右键单击 General 目录下的空白区域,然后选择 Add Components – Add Components from Update Site 选项。

在打开的 Update Site Details 对话框中,选择 Local Update Site 并导航到 Eclipse Workspace 的 ActivitiesUpdateSite 项目中的 site.xml 文件。在 Update Site 对话框的 Select Components 中,选择 Activities.view1 组件并单击 OK。现在组件面板上将出现该组件。

要将组件添加到应用程序,则将其拖放到导航器和组件面板之间的空白区域。会出现图 7 所示的对话框。选择 Install this plug-in 选项,并在出现提示时重新启动 Notes 客户机。


图 7. ActivitiesFeature Feature 对话框
ActivitiesFeature Feature 对话框

重新启动客户机时,按 Ctrl+O 打开一个应用程序,然后选择 Test Composite Application 选项。所打开的窗口如图 8 所示。


图 8. Test composite application 选项
Test composite application




回页首


向视图添加更多功能

现在已经成功解决与服务器的连接问题,并且能够从服务器检索信息,可以继续进行更复杂的任务。在以下章节中,将学习如何创建新活动以及如何从 Eclipse 视图中更新和删除现有活动。

首先,在执行所需功能的类中创建三个新方法,如清单 6 所示。


清单 6. 创建三个新方法


	private void createActivity(){
	}
	
	private void updateActivity(){
	}
	
	private void deleteActivity(){
	}


稍后将讨论这三个方法,不过现在先创建表的上下文菜单,其中包含三个操作:创建、更新和删除。为了表示这些操作,向 ViewPart1 类添加三个内部类,每个类将调用其中一个方法。每个内部类都扩展了 org.eclipse.jface.action.Action。重写构造函数和 run() 方法,以便实现所需功能。

将清单 7 中的内部类添加到 ViewPart1 类。


清单 7. 添加内部类

	private class CreateAction extends Action {
	  public CreateAction(){
		super();
		setText("Create");
	  }
	  public void run() {
		createActivity();
	  }
	}
	
	private class UpdateAction extends Action {
	  public UpdateAction(){
		super();
		setText("Update");
	  }
	  public void run() {
		updateActivity();
	  }
	}
	
	private class DeleteAction extends Action {
	  public DeleteAction(){
		super();
		setText("Delete");
	  }
	  public void run() {
		deleteActivity();
	  }
	}

下一步是创建上下文菜单并添加操作。将 createMenu() 方法添加到 ViewPart1 类,如清单 8 所示。


清单 8. 添加 createMenu() 方法

	private void createMenu() {
	  MenuManager menuMgr = new MenuManager("ContextMenu");
	  menuMgr.setRemoveAllWhenShown(true);
	  menuMgr.addMenuListener(new IMenuListener() {
		public void menuAboutToShow(IMenuManager manager) {
		  manager.add(new CreateAction());
	  manager.add(new UpdateAction());
		  manager.add(new DeleteAction());
		}
	  });
	  Menu menu = menuMgr.createContextMenu(_activitiesTable);
	  _activitiesTable.setMenu(menu);
	}

该方法首先将创建一个填充了上述三个操作的新 MenuManager。使用 MenuManager 对象创建添加到表中的 Menu。

最后,在 createPartControl() 方法的结尾处添加对 createMenu() 方法的调用,如清单 9 所示。


清单 9. 更新 createPartControl() 方法

	public void createPartControl(final Composite parent) {
		
	  …

	  getAllActivities();
	  createMenu();
	}





回页首


deleteActivity() 方法

首先讨论 deleteActivity() 方法,因为它最易于实现。第一步是确保已选择表中的某一项,使用 org.eclipse.swt.Table 类的 getSelectionCount() 方法进行确定。然后可以访问相关的数据对象,方法为对表项目调用 getData() 并将其传递到表示活动的 NodeSummary 对象。

因为该方法将从服务器删除活动,所以最好是与用户确认这是他/她所期望的操作。打开图 9 所示的对话框进行确认。


图 9. 对删除活动进行确认的对话框
对删除活动进行确认的对话框

使用 org.eclipse.jface.dialogs.MessageDialog 类的静态 openQuestion() 方法可以方便地显示该对话框。

MessageDialog.openQuestion(Display.getCurrent().getActiveShell(),
"Delete Activity", "Are you sure you wish to delete this activity?"
+selectedActivity.getName());

假定用户单击 Yes 按钮,则继续删除操作。将调用前面所创建的 OpenActivitiesClient 对象的 removeNode() 方法。在这里,还必须在 Job 中包含与服务器进行交互的代码,从而避免线程冲突。完整的方法如清单 10 所示。


清单 10. deleteActivity() 方法

	private void deleteActivity(){
	  if ( _activitiesTable.getSelectionCount() == 1 ){
		final NodeSummary selectedActivity = 
  (NodeSummary)_activitiesTable.getSelection()[0].getData();
		if ( selectedActivity != null ){
		  boolean delete = MessageDialog.openQuestion(
Display.getCurrent().getActiveShell(), 
			"Delete Activity", "Are you sure you wish to delete this 
activity? "+selectedActivity.getName());
		  if ( delete ){
			Job myJob = new Job ("Job"){
			  protected IStatus run(IProgressMonitor arg0) {
				try {
				  _activitiesClient.removeNode(
selectedActivity.getActivityUuid());
				} 
				catch (OpenActivitiesException e) {
				  e.printStackTrace();
				};
				getAllActivities();
				return Status.OK_STATUS;
			  }
			};
			myJob.schedule();
		  }
		}
	  }
	} 





回页首


创建用户输入对话框

允许用户输入或更新活动细节,这就要求输入很多不同的值。因此需要创建一个用来处理输入的简单对话框。右键单击活动包并选择 New – Class。输入 ActivityDialog 作为类名,并输入 org.eclipse.jface.dialogs.TitleAreaDialog 作为 Superclass。参见图 10。


图 10. New Java Class 对话框
New Java Class 对话框

创建类时,需要添加类变量和一个传递 Activity 对象的构造函数,如清单 11 所示。


清单 11. 添加类变量和构造函数

public class ActivityDialog extends TitleAreaDialog {
  private Activity _activity;
	  private Text _nameText;
	  private Text _descText;
  private Text _tagText;

  public ActivityDialog(Shell shell, Activity activity){
	super(shell);
	_activity = activity;
  }
}

为了使事情变得相对简单,仅设置活动的名称、描述和标记。这些标记仅仅是用来对相关信息进行分类的描述性术语。重写 TitleAreaDialog 类的 createDialogArea() 方法,使其包含清单 12 中的代码。


清单 12. 重写 createDialogArea() 方法

	protected Control createDialogArea(Composite parent) {
	  setTitle("Create/Update Activity");
	  setMessage("Enter or update details of the activity below");

	  GridLayout gl;
	  GridData gd;

	  Composite composite = new Composite(parent, SWT.NONE);
	  gd = new GridData();
	  gd.grabExcessHorizontalSpace = true;
	  gd.grabExcessVerticalSpace = true;
	  gd.horizontalAlignment = GridData.FILL;
	  gd.verticalAlignment = GridData.FILL;
	  composite.setLayoutData(gd);

	  gl = new GridLayout();
	  gl.marginWidth = 10;
	  gl.marginHeight = 10;
	  gl.numColumns = 2;
	  composite.setLayout(gl);

  Label nameLabel = new Label(composite,SWT.NONE);
	  nameLabel.setText("Activity Name:");
	  _nameText = new Text(composite,SWT.BORDER);
	  gd = new GridData();
	  gd.grabExcessHorizontalSpace = true;
	  gd.horizontalAlignment = GridData.FILL;
	  _nameText.setLayoutData(gd);
		
	  Label descLabel = new Label(composite,SWT.NONE);
	  descLabel.setText("Activity Description:");
	  _descText = new Text(composite,SWT.BORDER);
	  gd = new GridData();
	  gd.grabExcessHorizontalSpace = true;
	  gd.horizontalAlignment = GridData.FILL;
	  _descText.setLayoutData(gd);
		
	  Label tagsLabel = new Label(composite,SWT.NONE);
	  tagsLabel.setText("Tags:");
	  _tagsText = new Text(composite,SWT.BORDER);
	  gd = new GridData();
	  gd.grabExcessHorizontalSpace = true;
	  gd.horizontalAlignment = GridData.FILL;
	  _tagsText.setLayoutData(gd);
		
	  return composite;
}

尽管清单 12 看起来包含很多代码,但仔细观察会发现大部分代码是用来确保对话框具有可接受的布局。最后,重写 configureShell() 方法,如清单 13 所示,从而向对话框添加标题。


清单 13. 重写 configureShell() 方法


protected void configureShell(Shell shell) {
  super.configureShell(shell);
  shell.setText("Create/Update Activity");
}

在所打开的对话框中,可以输入以下值:

  • Activity Name
  • Activity Description
  • Tags

现在可以使用对话框功能了。因为已经设置了对话类变量中的所有文本字段,可以在 createDialogArea() 方法之外查看这些字段。因此,可以在已重写的 okPressed() 方法中访问它们,从而构建活动对象,如清单 14 所示。


清单 14. okPressed() 方法

protected void okPressed() {
	  _activity.setName(_nameText.getText());
	  _activity.setDescription(_descText.getText());
	  String [] tags = _tagsText.getText().split(",");
  for (int i=0; i<tags.length; i++){
		tags[i].trim();
	  }
	  _activity.setTagNames(tags);
	  super.okPressed();
	}

请注意,将使用 String.split(",") 方法来解析包含标记名的文本字段。将返回一个 String 对象数组,它们在原始文本中是通过逗号进行分隔的。还可以调用 String.trim() 方法来删除任何后导字符。

为了访问用户在对话框之外创建的活动,必须实现一个简单的 getActivity() 方法,它将返回 _activity 类变量。因此,添加以下方法:

public Activity getActivity(){
return _activity;
}

对话框的最后一步是进行一些修改,这样可以使用它来创建新活动或更新现有活动。这两种操作的主要区别在于更新一个活动时,需要向构造函数传递一个有效的 Activity 对象。否则,则为 null。将清单 15 中的代码添加到类。


清单 15. 实例化一个活动

	private void populateTextFields(){
	  if ( _activity != null ){
		if ( _activity.getName() != null ) {
		  _nameText.setText(_activity.getName());
		}
		if ( _activity.getDescription() != null ) {
		  _descText.setText(_activity.getDescription());
		}
		if ( _activity.getTagNamesString () != null ) {
		  _tagsText.setText(_activity.getTagNamesString());
		}
	  }
	  else {
		_activity = new Activity();
	  }
	}

该方法首先检查 _activity 类变量是否为非空;即检查是否将已实例化的 Activity 对象传递到构造函数,这表示正在更新活动。在这种情况下,将使用适当值填充对话框中的文本字段。反之,如果 _activity 为空,则使用新的空白 Activity 对象进行实例化,就像是用户正在创建新活动。

下面,在现有 createDialogArea() 方法中添加对 populateTextFields 方法的调用,如清单 16 所示。


清单 16. 更新 createDialogArea() 方法

protected Control createDialogArea(Composite parent) {

  …
	  populateTextFields();
	  return composite;
	}





回页首


createActivity() 方法

现在必须更新 createActivity() 方法,以便打开 ActivityDialog 实例。如果用户单击对话框中的 OK 按钮,则调用 getActivity() 方法来访问在服务器上创建新活动时所使用的值。通过调用 OpenActivitiesClient 类的 createActivity() 方法来实现上述操作。如前所述,必须在 Job 中包含与服务器的交互。对 createActivity() 方法进行编辑,使其包含清单 17 中的代码。


清单 17. createActivity() 方法


	private void createActivity(){
	  final ActivityDialog d = new ActivityDialog(
Display.getCurrent().getActiveShell(), null);
	  if (d.open() == Dialog.OK){
		Job myJob = new Job ("Job"){
		  protected IStatus run(IProgressMonitor arg0) {
			try {
			  _activitiesClient.createActivity(d.getActivity());
			} 
			catch (OpenActivitiesException e) {
			  e.printStackTrace();
			};
			getAllActivities();
			return Status.OK_STATUS;
		  }
		};
		myJob.schedule();
	  }
	} 

还需注意,向 ActivityDialog 的构造函数传递了 null。这样可以确保创建新活动而不是更新现有活动。





回页首


updateActivity() 方法

不必奇怪,updateActivity() 方法与 createActivity() 方法非常相似。但是,有两点主要区别。第一,编辑表中的现有活动时,必须确保表中有一个活动被选中。也可以使用 getSelectionCount() 方法进行确认。

还必须认识到表中的数据对象是 NodeSummary 类的实例,而 OpenActivitiesClient 的 updateActivity() 方法需要 Activity 对象。为了解决这个问题,使用 OpenActivitiesClient 类的 getActivityByUuid() 方法返回实际的 Activity 对象。创建一个类变量来存储该对象,因此可以在类中任何地方对它进行访问:

private Activity _activityToUpdate;

该方法包含两个 Job。第一个 Job 将填充 Activity 对象,这样可以在第二个 Job 中访问它,而第二个 Job 实际更新活动。因此,必须确保在执行第二个 Job 之前已经完成第一个 Job。为了实现上述操作,调用 Job.join() 方法,它将阻止调用线程直到完成第一个 Job。完整的方法如清单 18 所示。


清单 18. updateActivity() 方法

	private void updateActivity(){
	  if ( _activitiesTable.getSelectionCount() == 1 ){
		final NodeSummary selectedActivity = (NodeSummary)
  _activitiesTable.getSelection()[0].getData();
		_activityToUpdate = null;

		if ( selectedActivity != null ){
		  Job myJob = new Job ("Job"){
			protected IStatus run(IProgressMonitor arg0) {
			  try {
				_activityToUpdate = _activitiesClient.getActivityByUuid(
  selectedActivity.getActivityUuid());
			  }
			  catch (OpenActivitiesException e) {
				e.printStackTrace();
			  }
			  return Status.OK_STATUS;
			}
		  };
		  myJob.schedule();
		  try {
			myJob.join();
		  }
		  catch (InterruptedException e) {
			e.printStackTrace();
		  }
		}

		if ( _activityToUpdate != null ){
		  final ActivityDialog d = new ActivityDialog(
Display.getCurrent().getActiveShell(), _activityToUpdate);
		  if (d.open() == Dialog.OK){
			Job myJob2 = new Job ("Job2"){
			  protected IStatus run(IProgressMonitor arg0) {
				try {
				  _activitiesClient.updateActivity(d.getActivity());
				} 
				catch (OpenActivitiesException e) {
				  e.printStackTrace();
				};
				getAllActivities();
				return Status.OK_STATUS;
			  }
			};
			myJob2.schedule();
		  }
		}
	  }
	}





回页首


更新复合应用程序

现在已经完成所有插件代码的编写。最后一步是使用已修改的代码来更新复合应用程序。若要实现上述操作,更新插件版本和特性,以便 Lotus Notes 客户机重新使用它们。

使用 Plug-in Manifest Editor 打开 Activities 插件的 plugin.xml 文件,然后选择 Overview 附签。将插件的版本更改为 1.0.1。

下面对 ActivitiesFeature 项目进行同样操作:将特性版本更改为 1.0.1。最后一步是更新 ActivitiesUpdateSite 项目中所包含的 site.xml 文件。首先,右键单击现有的 ActivitiesFeature 1.0.0 特性,然后选择 Remove。接着添加刚刚更新的特性 ActivitiesFeature 1.0.1。

重新启动客户机后,打开已更新的复合应用程序,类似于图 11 所示。Create/Update Activity 对话框中所显示的字段具有以下值:

  • Activity Name:My activity updated
  • Activity Description:My activity description
  • Tags:michael、activities、composite application

图 11. 已更新的复合应用程序
已更新的复合应用程序




回页首


结束语

在本文中,学习了如何创建 Eclipse 视图组件以及如何将其添加到新复合应用程序。组件使用 Activities API 来创建、读取、更新和删除 Activities 服务器上的活动。

还学习了如何使用 Lotus Notes V8 的 Accounts Manager 特性来提取用户证书,然后使用证书连接 Activities 服务器。其他讨论的主题还包括在开发 Lotus Notes 客户机时使用 Job 和 UIJob 改善性能,以及利用 Standard Widget Toolkit 来改善整体的用户体验。






回页首


下载

描述名字大小下载方法
示例代码SourceCode.zip48 KBHTTP
关于下载方法的信息


参考资料

学习

获得产品和技术

讨论


关于作者

Michael Crawford 是 IBM Dublin Software Lab 的一名软件开发人员,目前正在开发 IBM Lotus Notes V8 的复合应用程序编辑器。他曾就读于阿尔斯特大学,在完成 Extreme Blue 实习计划后于 2005 年加入 IBM。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

将您的建议发给我们或者通过参加讨论与其他人分享您的想法.




回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款