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原始碼,一定能找到相關程式碼的實現。