轉:【Eclipse外掛開發】開啟編輯器

zgy13121發表於2008-09-25

轉:【Eclipse外掛開發】開啟編輯器 http://www.blogjava.net/zhuxing/archive/2008/08/27/225041.html

//建立工程
IProject project = ResourcesPlugin.getWorkspace().getRoot()
.getProject("TestProject");
if (!project.exists())
project.create(null);
if (!project.isOpen())
project.open(null);

//建立檔案
IFile java_file = project.getFile(new Path("/java_file.java"));

InputStream inputStreamJava = new ByteArrayInputStream(
"class MyType{}".getBytes());
if (!java_file.exists())
java_file.create(inputStreamJava, false, null);
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
IDE.openEditor(page, java_file);

注意要引入以下幾個:否則會找不到相應的類

org.eclipse.ui

org.eclipse.core.runtime

org.eclipse.core.resources

org.eclipse.core.varibles

org.eclipse.ui.ide

[@more@]今天終於可以閒一天,想來想去就亂寫點東西吧,說不定對有些新人有點幫助呢~_~ 用Eclipse API的方式來開啟編輯器,可能對任何一個外掛開發者都不是很陌生的操作了。但是,還是建議你忍著看一下,全當是複習吧~_~。 【開啟editor的介面討論】 先來看一下workbench吧,workbench從靜態劃分應該大致如下: 從結構圖我們大致就可以猜測出來,workbench page作為一個IWorkbenchPart(無論是eidtor part還是view part)的容器,肯定會接受workbench page的管理。看了一下,IWorkbenchPage介面定義中確實提供給瞭如下開啟編輯器的操作: 【IWokbenchPage提供的介面】 1 public interface IWorkbenchPage extends IPartService, ISelectionService,ICompatibleWorkbenchPage { 2 3 public IEditorPart openEdito(IEditorInput input, String editorId)throws PartInitException; 4 5 public IEditorPart openEdito(IEditorInput input, String editorId, boolean activate) throws PartInitException; 6 7 public IEditorPart openEditor(final IEditorInput input, final String editorId, final boolean activate, final int matchFlags)throws PartInitException; 8 } 那到這邊,可能很多人已經知道了怎麼呼叫這些介面了: PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().openEditor(...) (說明:PlatformUI可以看作是整個eclipse ui框架的門面類,當然最核心的作用就是讓使用者獲取到workbench。Eclipse中存在的其他一些門面類如:ResourcesPlugin、Platform、JavaCore、JavaUI等) 我們再仔細看一下IWorkbenchPage對應的實現類(org.eclipse.ui.internal.WorkbenchPage)中的以上介面的實現程式碼,真正在管理Editor的是一個叫做EditorManager的東東(同理,view part對應的管理器角色類是叫做ViewFactory的東東)。這裡的EditorManager和View Factory是workbench實現中非常精華的部分,看一下里面的實現就會很大程度上理解workbench所謂懶載入、懶初始化是如何實現的了,如何實現part 複用的...等等。 上圖就用來說明workbench是如何來管理各種part的,其中descriptor角色的核心作用是延遲載入擴充套件(延遲載入使用者透過editors或者views提供的擴充套件),reference角色的核心作用是用來延遲初時化具體的part(例如避免過早的建立對應的control等等)。再說下去有點偏離主題了,這部分,以後有時間再寫 【IDE工具類提供的介面】 上面IWorkbenchPage提供介面都需要使用者準備兩樣東西:一是建立IEditorInput例項,二是指定editor id。有些使用者可能不想幹這兩件事情,所以在工具類org.eclipse.ui.ide.IDE中提供了其他的介面: 1 public static IEditorPart openEditor(IWorkbenchPage page, IFile input) throws PartInitException { } 2 3 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, boolean activate) throws PartInitException { } 4 5 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, boolean activate, boolean determineContentType) { } 6 7 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId) throws PartInitException { } 8 9 public static IEditorPart openEditor(IWorkbenchPage page, IFile input, String editorId, boolean activate) throws PartInitException { } 10 11 上面5個介面操作中, 對於上面的三個操作,Eclipse會自動為你準備IEditorInput例項,並動態繫結合適的編輯器型別。對於下面的兩個操作,Eclipse會為你自動準備IEditorInput例項,但是需要使用者自己指定editor id。 接下來我們看兩個問題,一是如何建立IEditorInput例項的;而是如何動態計算對應的editor id的。 【有關FileEditorInput】 在IDE工具類中提供的5個接受IFile物件的openEditor介面中,在對應的實現中都是預設構造了一個FileEditorInput(org.eclipse.ui.part.FileEditorInput)例項,這個例項也是org.eclipse.ui.IFileEditorInput介面的預設實現類(注意:Eclipse中很多地方都使用這種Interface/Default Impl的方式,Interface會暴露,Default Impl則根據情況選擇是否暴露,一般是如果Interface希望使用者來擴充套件繼承,則會暴露對應的Default Impl,如果Interface不希望使用者來擴充套件繼承,例如IResource系列介面,則一般會將Default Impl丟如對應的internal包中)。 我們看一下org.eclipse.ui.part.FileEditorInput中是如何實現IEditorInput.exists()介面的: 1 public class FileEditorInput implements IFileEditorInput,IPathEditorInput,IPersistableElement { 2 private IFile file; 3 4 public boolean exists() { 5 return file.exists(); 6 } 7 } 我們看到內部的實現是持有了IFile控制程式碼,如果IFile代表的資源沒有存在於工作區之內,那麼就會返回false。(疑問:如果我們開啟工作區外部的檔案呢???顯然,FileEditorInput並不合適,稍後看...) 【動態計算editor id】 下面,我們再來看一下IDE類是如何計算所謂的預設eidtor id的。追蹤實現,我們看到了IDE.getDefaultEditor 1 public static IEditorDescriptor getDefaultEditor(IFile file, boolean determineContentType) { 2 // Try file specific editor. 3 IEditorRegistry editorReg = PlatformUI.getWorkbench() 4 .getEditorRegistry(); 5 try { 6 String editorID = file.getPersistentProperty(EDITOR_KEY); 7 if (editorID != null) { 8 IEditorDescriptor desc = editorReg.findEditor(editorID); 9 if (desc != null) { 10 return desc; 11 } 12 } 13 } catch (CoreException e) { 14 // do nothing 15 } 16 17 IContentType contentType = null; 18 if (determineContentType) { 19 contentType = getContentType(file); 20 } 21 // Try lookup with filename 22 return editorReg.getDefaultEditor(file.getName(), contentType); 23 } 上面的程式碼大致趕了如下兩件事情: 1、如果對應的資源設定了一個特定的持久化屬性EDITOR_KEY,則會使用EDITOR_KEY屬性值所代表的編輯器(說明:有關Eclipse資源的屬性支援,請參閱其他文件)。那如果一個資源不在工作區之內,又如何設定EDITOR_KEY屬性呢??? (~_~確實沒法設定) 2、查詢對應的content type,使用者透過org.eclipse.core.runtime.contentTypes擴充套件點來註冊自定義的內容型別,在內容型別中會指定對應的副檔名和預設編碼,例如JDT中註冊瞭如下內容型別(摘自org.eclipse.jdt.core/plugin.xml): 那如果我們在註冊編輯器的時候和對應的content type繫結,這不就聯絡起來了嗎~_~。那我們看一下java原始碼編輯器擴充套件描述(摘自org.eclipse.jdt.ui/plugin.xml): 我們看到上面的xml中有contentTypeBinding元素,裡面指定了繫結java原始碼content type。 那如果我們在註冊編輯器的時候,沒有繫結對應的content type呢?Eclipse允許你配置,往下看: 我想看到這邊對eclipse如何動態計算一個檔案對應的editor應該是明白了吧,再回顧一下吧: 1、檢視資源本身是否有EIDTOR_ID持久屬性(注意:一、只有工作區中存在的資源才允許設定持久屬性;二、資源屬性知識針對特定資源,不會影響同型別資源,即你對工作區中特定的.java檔案設定了EIDTOR_ID持久屬性,並不會影響工作區中其他.java檔案資源的編輯器繫結操作) 2、查詢對應的content type,然後查詢對應的editor擴充套件或者查詢Eclipse中的Content Types和File Associations配置 3、如果都找不到,則直接給一個預設的編輯器。例如,我們經常碰到是"org.eclipse.ui.DefaultTextEditor" 【IDE工具類提供的介面 VS IWorkbenchPage提供的介面】 看一下以上提到的各個角色之間的呼叫關係圖吧: 【使用Eclipse提供的開啟editor的介面】 還是那句話,需求決定一切。我們看一下開啟編輯器的需求: 1、開啟工作區中工程內的檔案資源 2、開啟工作區.metadata目錄中的檔案資源 3、開啟工作區外部的檔案資源 【說明】Eclipse工作區實際上是有資料區和後設資料區兩個區域組成的,示意如下: 對於Eclipse來說,.metadata目錄下存放的是外掛執行時的關鍵狀態資料,不建議使用者再工作區例項執行期間做相應修改,為此eclipse幹了兩件事情:1、執行期間會自動在.metadata目錄下產生一個程式鎖定的.lock檔案;2、Eclipse不允許使用者透過IResource系列介面直接訪問或修改.meatadata目錄下的資源 【開啟工作區工程內的資源】 假設工作區中有測試工程TestProject,工程下有文字檔案java_file.txt。對應建立程式碼如下: 1 try { 2 //建立工程 3 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); 4 if (!project.exists()) 5 project.create(null); 6 if (!project.isOpen()) 7 project.open(null); 8 9 //建立檔案 10 IFile java_file = project.getFile(new Path("/java_file.txt")); 11 InputStream inputStreamJava = new ByteArrayInputStream("class MyType{}".getBytes()); 12 if (!java_file.exists()) 13 java_file.create(inputStreamJava, false, null); 14 } catch (CoreException e) { 15 IStatus status = new Status(IStatus.ERROR, "myplugin", 101, "建立資源失敗", e); 16 Activator.getDefault().getLog().log(status); 17 } 開啟方式一:Eclipse預設計算對應的editor id,會用default text editor開啟 1 try { 2 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 3 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); 4 5 IFile java_file = project.getFile(new Path("/java_file.txt")); 6 IDE.openEditor(page, java_file); 7 } catch (CoreException e) { 8 IStatus status = new Status(IStatus.ERROR, "myplugin", 102, "開啟工作區內檔案出錯", e); 9 Activator.getDefault().getLog().log(status); 10 } 開啟方式二:指定java原始碼編輯器開啟,會用java原始碼編輯器開啟 1 try { 2 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 3 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); 4 5 IFile java_file = project.getFile(new Path("/java_file.txt")); 6 IDE.openEditor(page, java_file, "org.eclipse.jdt.ui.CompilationUnitEditor"); 7 } catch (CoreException e) { 8 IStatus status = new Status(IStatus.ERROR, "myplugin", 102, "開啟工作區內檔案出錯", e); 9 Activator.getDefault().getLog().log(status); 10 } 開啟方式三:設定editor id屬性,該檔案以後預設都用此editor id開啟 1 try { 2 IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage(); 3 IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("TestProject"); 4 5 IFile java_file = project.getFile(new Path("/java_file.txt")); 6 java_file.setPersistentProperty(IDE.EDITOR_KEY, "org.eclipse.jdt.ui.CompilationUnitEditor"); 7 IDE.openEditor(page, java_file); 8 } catch (CoreException e) { 9 IStatus status = new Status(IStatus.ERROR, "myplugin", 102, "開啟工作區內檔案出錯", e); 10 Activator.getDefault().getLog().log(status); 11 } 說明:對於工作區工程內的資源,可以有兩種方式:一是local的,那就是物理存在與工程之內;二是link進入的。開啟編輯器的時候,不需要做區分。 【開啟工作區外部的資源】 說明:既存在於工作區外部,同時又沒有被link進工程。 在Eclipse中有個功能,就是File->Open File,可以開啟一個外部檔案。那我們看一下它是怎麼實現的。我們只需要開啟對應的對話方塊,然後掛起主執行緒,就可以找到對應的action了(掛起執行緒可以幫我們很方便的除錯很多型別的問題,以後細說~_~): 分析一下OpenExternalFileAction的實現,我們發現它自己構建了一個editor input

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/11419868/viewspace-1011023/,如需轉載,請註明出處,否則將追究法律責任。

相關文章