读书人

Workspace Resource框架课题(3)处理

发布时间: 2013-05-02 09:39:29 作者: rapoo

Workspace Resource框架专题(3)处理工作空间资源更改事件
3? 处理工作空间资源更改事件
  工作空间API允许工具对它所感兴趣的资源更改事件进行注册。您可以使用资源更改侦听器来对事件作出响应或执行相应动作,甚至自动执行某些任务。例如,资源更改侦听器可以用于管理Bookmarks视图中的条目。从资源中添加或删除书签标记将触发一次资源更改事件。Bookmarks视图则侦听到该事件,并且判断是否需要对它作出响应。并不是所有的事件发生都要求Bookmarks视图作出相应的更改。而是Bookmarks视图所使用的资源更改侦听器可以快速地判断是否有书签标记发生更改,如果需要,作出相应的反应。用户可以看到视图对更改作出的即时反应(为了测试,您可以打开Bookmarks视图,然后向一个文件中添加一个或两个书签)。
3.1? 使用工作空间API跟踪更改
  可以使用IWorkspace.addResourceChangeListener(...)方法将资源更改侦听器添加到工作空间中。该方法允许您的侦听器接收来自于更改事件的通知,这些更改事件包括:
●?????? 添加、修改、移动或删除文件。
●?????? 打开或关闭项目。
●?????? 添加或删除标记。
●?????? 构建器事件即将启动或已完成。
  表1-3中所列的接口用于实现对资源更改侦听器的支持,包括支持创建资源更改侦听器、处理接收到的事件以及访问与资源相关联的资源变化(resource delta)。侦听器是实现IResourceChangeListener接口的一个类,其中定义了resourceChanged方法。该方法可以通过传入的IResourceChangeEvent参数查询事件的类型。适当的时候,侦听器可以获得一个IResourceDelta对象,该对象包含更改受事件影响的资源的细节。
表1-3? 资源更改事件接口


图1-5? 带有一个资源更改侦听器的事件处理过程
  一般情况下,用户在使用Eclipse时并不会启动插件,直到有需要时,才会启动。在插件的启动过程中,它可以向工作空间添加资源更改事件。只有那些发生在侦听器添加之后的事件,插件才会收到通知,因此,正如图1-5所示,资源更改侦听器只会收到资源更改事件D和E的通知。
3.2? 添加资源更改侦听器
您可以使用下面任何一种方法向工作空间添加资源更改侦听器,之后,您将会收到所侦听的更改事件的通知。
  addResourceChangeListener(
    IResourceChangeListener 1istener)
  addResourceChangeListener(
    IResourceChangeListener listener, int eventMask)
  第一种方法是添加一个基本的侦听器,它将收到发生的所有非构建的资源更改事件(关闭、删除和更改)。第二种方法则允许您在添加侦听器时使用一个事件屏蔽参数,以选择发送到侦听器的资源更改事件类型。通过这种方法,您可以过滤掉任何您认为不需要处理的事件。表1-4列出了各种可以发送到侦听器的资源更改事件类型。
表1-4? 资源更改事件类型
  break;
  case IResourceChangeEvent.PRE_DELETE :
  System.out.println(
   "Deleting : " + event.getResource().getFullPath());
  break;
  case IResourceChangeEvent.PRE_AUTO_BUILD :
  System.out.print1n(" -> Auto build about to run.");
  break;
  case IResourceChangeEvent.POST_AUTO_BUILD :
  System.out.println(
   " -> Auto build complete, visiting the delta...");
  try {
  event.getDelta().accept(
   new Simp1eResourceDe1taVisitor());
  } catch (CoreException e) {
   System.out.println(e);
  }
  break;
  case IResourceChangeEvent.POST_CHANGE :
  System.out.print1n(
   " -> Resource(s) changed, visiting the delta...");
  try {
  event.getDelta().accept(
   new SimpleResourceDeltaVisitor());
  } catch (CoreException e) {
   System.out.println(e);
  }
   }
  }
  该段代码也展示了,当事件提供了一个资源变化时(仅POST_事件),如何从传递给资源更改侦听器的事件中获取资源变化。如上所示,event.getDelta方法可以用于获取一个IResourceDelta对象的引用。除此之外,还需要一个访问者来查找资源变化中所标识的更改。
  您也可以直接访问资源变化以确定是否是您所感兴趣的资源发生了更改。这种方式允许您基于路径来查询资源变化:
  event.getDelta().findMember(IPath);
  相对于访问整个资源变化树的方法,该方法更加高效,但是您必须拥有一个您所感兴趣的具体文件或文件夹,以便进行查询。
  
3.3? 资源更改事件触发的时序
  当资源已经以某种方式发生更改,并作为构建事件周期的一部分时,会触发资源更改事件。您无法保证两种类型的事件发送的先后次序(更改事件和构建事件)。
  当资源发生更改时,无论它是添加、修改、删除或移动操作,还是对于资源的标记进行更改,都会触发一次资源更改事件。同样地,项目状态的更改也会触发一次资源更改事件。这些事件均在一个通知周期内被传递。当资源被修改时,也会触发构建事件,然后,这些事件会在不同的通知周期内被传递。
  用一个简单例子来说明这一点。假设您拥有3个资源更改侦听器,一个仅侦听POST_CHANGE事件,一个仅侦听PRE_BUILD事件,另一个同时侦听这两个事件。我们称这些侦听器依次为A、B和C。如果您即将删除一个资源,侦听器A和C将会被调用,并作为更改通知周期的一部分;然后,侦听器B和C被调用,并作为构建通知周期的一部分。够简单吧,让我们继续下面的内容。
  我们假定如下情形,在一次操作调用过程中,产生了5次不同的资源更改。由于这些事件迅速地被触发,工作空间将按照轮流的方式把所有5次更改事件传递给A和C(A、C、A、C等)。传递完这些事件之后,再将构建事件传递给B和C。这些资源更改侦听器只会被调用一次,但是它们可以通过资源变化访问所有5次资源更改的信息。
  下面是试验的结果:如果您的程序从容地产生资源更改,您可能会看见构建事件在更改事件之间默默地暗中进行。您可以在Eclipse平台项目网站eclipse.org的项目页面上以及Eclipse帮助系统中找到关于发送资源更改事件的更为详细的信息。
3.4? 访问资源变化
  访问者可以通过访问者模式对资源更改事件所提供的资源变化进行处理。为此,访问者必须实现IResourceDeltaVisitor接口,该接口允许访问者处理资源变化。通过该接口,访问者可以访问每个更改事件,并且实现任何需要进行的处理(参见图1-6)。



图1-6? 访问资源变化
  为了创建访问者,请在类中实现IResourceDeltaVisitor接口,该接口要求其实现类拥有一个visit方法。为了获取资源变化并结合访问者进行处理,您可以在资源更改侦听器中使用如下程序代码;
  event.getDelta().accept(new SimpleResourceDeltaVisitor());
  下面是一个实现资源变化访问者中的visit方法的简单示例。
  public boolean visit(IResourceDelta delta)
  throws CoreException {
  IResource res?= delta.getResource();
  switch (delta.getKind()) {
  case IResourceDelta.ADDED :
  System.out.println(
   "Resource " +?res.getFullPath()?+ " was added.");
  break;
  case IResourceDelta.REMOVED :
  System.out.println(
   "Resource " +?res.getFullPath()?+ " was removed.");
  break;
  case IResourceDelta.CHANGED :
  System.out.print1n(
   "Resource " +?res.getFullPath()?+ " has changed.");
  break;
  }
  return true; // Continue the visit process.
  }
  该例子通过查询资源变化来标识资源更改的类型。此外,资源变化也包含了更改事件的其他信息。对于PRE_BUILD、POST_BUILD和POST_CHANGE类型的资源更改事件,资源变化还将包含标记的更改信息。
如下示例说明了如何通过变化查找更改的其他详细信息。
  int eventFlag = delta.getFlags();
  if ((eventFlag &?IResourceDelta.CONTENT)?!= 0)
   traceMsg("-->?Content Changed");
  if ((eventFlag &?IResourceDelta.REPLACED)?!= 0)
   traceMsg("--> Content Replaced");
  if ((eventFlag &?IResourceDelta.REMOVED)?!= 0)
   traceMsg("-->?Removed");
  if ((eventFlag &?IResourceDelta.MARKERS)?!= 0)
   traceMsg("--------------------> Marker Changed");
  关于资源更改事件的各种标志类型在IResourceDelta类中被定义为常量。这些常量已经在表1-5进行了汇总。
表1-5? 资源更改事件标志
  IMarker marker = markerDelta.getMarker();
  System.out.piint1n("\t Marker itself: "
   + marker + marker.getType());
  System.out.print1n("\t Marker?content: "
   + marker.getAttributes());
  System.out.println("<--------------------");
  }
3.5? 资源变化内容
  资源变化可以包含多个更改事件的内容。例如,如果您向一个文件夹(aFolder)添加一个文件(a.file),将在资源变化中看到如下更改:
  / changed (workspace root)
  /a.project changed
  /a.project/aFolder changed
  /a.project/aFolder/a.file?added
  有些针对资源模型的更改可以触发多个事件。例如,关闭一个项目,将触发PRE_CLOSE事件,以确认一次关闭操作。此外,关闭项目的同时还会从工作空间中删除项目所包含的资源,因此,PRE_BUILD、POST_BUILD和POST_CHANGE资源更改事件也会被触发。如果您在刚添加完a.file文件后关闭当前项目,将在资源变化中看到如下更改:
  / changed (workspace root)
  /a.project changed
  /a.project/aFolder removed
  /a.project/aFolder/a.file removed
  关闭项目时,项目并不会从资源模型中删除,而是以关闭状态存在。但如果删除一个项目,则资源更改事件PRE_DELETE、PRE_BUILD、POST_BUILD和POST_CHANGE会被触发。PRE_DELETE事件包含正在删除的项目,而其他资源更改事件则包含一个资源变化,该资源变化的内容如下:
  / changed (workspace?root)
  /a.project removed
  /a.project/aFolder removed
  /a.project/aFolder/a.fi1e removed
--------------------
说明:
参考资料来源--《Eclipse 权威开发指南(第2版)》
这是一本译著,原名《The Java Developer’s Guide to Eclipse》 2nd Edition, 这本还是比较全面和深入的讲解了Eclipse开发中的各个部分的感念和原理的,不适合入门,做过一段时间的开发后阅读比较好。

读书人网 >开源软件

热点推荐