1. 程式人生 > >eclipse 資源監聽

eclipse 資源監聽

  資源監聽器

  Eclipse外掛實現資源監聽的主要方式是實現資源監聽器,通過資源監聽器,外掛就能夠保證Workspace中的資源和模型同步。另外,資源監聽器還能知道當前什麼資源被改變,以及怎樣被改變了。

  資源監聽器要實現IResourceChangeListener介面,並能通過IWorkspace的addResourceChange Listener方法註冊。當不再需要資源監聽器時,一定要呼叫removeResourceChangeListener方法把監聽器從IWorkspace中刪除。

  IResourceChangeListener介面的定義如例程1所示。

  例程1 IResourceChangeListener.java

  package org.eclipse.core.resources;

  import java.util.EventListener;

  public interface IResourceChangeListener extends EventListener {

  public void resourceChanged(IResourceChangeEvent event);

  }

  IResourceChangeListener介面中只定義resourceChanged方法,當資源改變後,將會執行IResourceChangeListener例項的resourceChanged方法。實現IResourceChangeListener介面如下程式碼所示。

  IResourceChangeListener listener = new IResourceChangeListener() {

  public void resourceChanged(IResourceChangeEvent event) {

  System.out.println("Something changed!");

  }

  };

  上例實現了一個簡單的資源監聽器,其中IResourceChangeEvent表示資源改變的事件的物件,通過IResourceChangeEvent,使用者獲得資源改變的物件,例如“event.getDelta();”。實現資源監聽器後,使用者要負責把監聽器註冊到Workspace中,最後還應該刪除註冊的監聽器,步驟如下。

  (1)獲得Workspace的例項,例如“IWorkspace workspace = ResourcesPlugin.get Workspace();”。

  (2)註冊資源監聽器,例如“workspace.addResourceChangeListener(listener);”。

  (3)刪除資源監聽器,例如“workspace.removeResourceChangeListener(listener);”。

  資源訪問器

  在Workspace中,資源是以樹型結構組織的,使用者可以通過樹型結構訪問被改變的資源樹。通常,使用者應該實現IResourceDeltaVisitor介面,以實現改變資源的訪問。IResourceDeltaVisitor介面定義如例程2所示。

  例程2 IResourceDeltaVisitor.java

  package org.eclipse.core.resources;

  import org.eclipse.core.runtime.CoreException;

  public interface IResourceDeltaVisitor {

  public boolean visit(IResourceDelta delta) throws CoreException;

  }

  IResourceDeltaVisitor介面只定義visit方法,其中引數IResourceDelta表示Workspace中資源樹的改變物件。IResourceDeltaVisitor的實現類只要實現visit方法即可,如例程3所示。

  例程3 Visitor.java

  class Visitor implements IResourceDeltaVisitor {

  public boolean visit(IResourceDelta delta) {

  switch (delta.getKind()) {

  case IResourceDelta.ADDED :

  break;

  case IResourceDelta.REMOVED :

  break;

  case IResourceDelta.CHANGED :

  break;

  }

  return true;

  }

  }

  IResourceDelta有一些整型的常量,指明瞭當前被改變資源的狀態,例如“ADDED、NO_CHANGE、REMOVED”等,IResourceDelta有一個實現類ResourceDelta,通過ResourceDelta的accept方法,結合IResourceDeltaVisitor的實現類,共同實現了Visit設計模式。accept方法的實現如以下程式碼片段所示。

  public void accept(IResourceDeltaVisitor visitor) throws CoreException {

  accept(visitor, 0);

  }

  public void accept(IResourceDeltaVisitor visitor, int memberFlags)

  throws CoreException {

  final boolean includePhantoms = (memberFlags & IContainer.INCLUDE_PHANTOMS) != 0;

  final boolean includeTeamPrivate =

  (memberFlags & IContainer.INCLUDE_TEAM_PRIVATE_MEMBERS) != 0;

  int mask = includePhantoms ? ALL_WITH_PHANTOMS : REMOVED | ADDED | CHANGED;

  if ((getKind() & mask) == 0)

  return;

  if (!visitor.visit(this))

  return;

  for (int i = 0; i < children.length; i++) {

  ResourceDelta childDelta = children[i];

  if (!includeTeamPrivate && childDelta.isTeamPrivate())

  continue;

  if (!includePhantoms && childDelta.isPhantom())

  continue;

  childDelta.accept(visitor, memberFlags);

  }

  }

  如以上程式碼所示,ResourceDelta和IResourceDeltaVisitor的實現類結合起來,實現了Visitor設計模式。Eclipse中還使用了很多的設計模式,實現了Eclipse中很多核心的功能,有興趣的讀者可以先參考設計模式的實現,然後查詢Eclipse中的實現,相信更有助於讀者進一步理解設計模式的實現,而且對理解Eclipse核心的實現是非常有幫助的。

  資源監聽的實現

  要實現資源監聽器,並根據資源改變的內容處理資源改變事件,使用者應該先實現IResourceChangeListener介面,並把監聽器註冊到Workspace中。另外,可以通過實現IResourceDeltaVisitor介面,訪問修改的內容,如例程4所示。

  例程4 DocIndexUpdater.java

  public class DocIndexUpdater implements IResourceChangeListener {

  //顯示列表

  private TableViewer table;

  private static final IPath DOC_PATH = new Path("MyProject/doc");

  //響應資源改變事件

  public void resourceChanged(IResourceChangeEvent event) {

  //處理POST_CHANGE事件

  if (event.getType() != IResourceChangeEvent.POST_CHANGE)

  return;

  //獲得改變的物件

  IResourceDelta rootDelta = event.getDelta();

  IResourceDelta docDelta = rootDelta.findMember(DOC_PATH);

  if (docDelta == null)

  return;

  //建立改變的列表

  final ArrayList changed = new ArrayList();

  IResourceDeltaVisitor visitor = new IResourceDeltaVisitor() {

  public boolean visit(IResourceDelta delta) {

  //處理IResourceDelta.CHANGED事件

  if (delta.getKind() != IResourceDelta.CHANGED)

  return true;

  if ((delta.getFlags() & IResourceDelta.CONTENT) == 0)

  return true;

  IResource resource = delta.getResource();

  //只處理副檔名為txt的檔案

  if (resource.getType() == IResource.FILE &&

  "txt".equalsIgnoreCase(resource.getFileExtension())) {

  //把改變的內容新增到列表

  changed.add(resource);

  }

  return true;

  }

  };

  try {

  //通過Visitor模式,遍歷docDelta

  docDelta.accept(visitor);

  } catch (CoreException e) {

  }

  if (changed.size() == 0)

  return;

  //顯示在table中

  Display display = table.getControl().getDisplay();

  if (!display.isDisposed()) {

  display.asyncExec(new Runnable() {

  public void run() {

  //確認table是否存在

  if (table.getControl().isDisposed())

  return;

  table.update(changed.toArray(), null);

  }

  });

  }

  }

  }

  如上程式碼實現了資源監聽器,當資源為txt檔案時,把檔案顯示在table中,使用者可以通過監聽器找到被改變的資源。

  提示:Eclipse框架還支援很多其他監聽器的實現,例如“IPartListener”,在此無法介紹全面,讀者可以查詢Eclipse原始碼,一定能找到相關程式碼的實現。