熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java開源技術 >> 正文

擴展Eclipse的Java開發工具(三)

2013-11-23 20:08:39  來源: Java開源技術 

  如何擴展 JDT 的特定元素的用戶界面(象 Outline 視圖中的成員)?擴展視圖還是它們的底層模型?
  簡單的Hello World示例顯示了添加菜單選項只需要在插件清單文件中添加幾行 XML()以及一個處理實際操作的類(comibmlabhelloworldSampleAction)向視圖的下拉菜單公共編輯器的工具欄以及彈出菜單添加操作基本上很簡單所提供的彈出菜單歸結為兩類一類只與視圖相關而與所選的對象無關(也就是對視圖的空白處單擊鼠標右鍵通常會顯示的缺省彈出菜單)另一類則更常見它們與應用於所選對象的選項相關在我們的例子中我們希望目標只是具體選擇的對象所以通過在插件清單文件中定義一個擴展我們將提供的操作對象提供給這些對象的彈出菜單(對下面幾個標識符進行了縮寫以獲得更佳的格式表示)如清單 所示
  
  清單 修飾符操作
  
  <extension point=orgeclipseuipopupMenus>
   <objectContribution
     objectClass=reIMember
     id=imember>
     
    <menu
      label=Soln: Modifiers
      path=groupreorganize
      id=imembermodifiers>
     <separator name=group/>
     <separator name=group/>
    </menu>
    
    <action
     label=Private
     menubarPath=imembermodifiers/group
     class=jdtexcerptMakeIMemberPrivateAction
     id=imembermakeprivate>
    </action>
    
    <action
     label=Protected
     menubarPath=imembermodifiers/group
     class=jdtexcerptMakeIMemberProtectedAction
     id=imembermakeprotected>
    </action>
    
    all menu choices not shown
    
   </objectContribution>
  </extension>
  
  擴展點命名為 orgeclipseuipopupMenus顧名思義它定義了向出現在工作台中的彈出菜單提供的對象這個特殊示例只提供給明確選擇的對象即實現 IMember 接口的對象(請回憶一下 Java 語言規范中的定義成員包含方法和字段)我們的研究沒有白費我們得到了當前問題的答案我們差不多准備好回答下一個問題了
  
  在這樣做之前此時請注意我們找到的用於簡單Hello World操作示例的模式將對所提供的其它菜單操作進行重復將把選擇更改告知 class 屬性中指定的類(通過其 selectionChanged 方法)並還將告知它用戶何時選擇菜單選項(通過其 run 方法)我們旅行的用戶界面部分快要結束了更困難的部分也是影響我們所期望更改的部分還在前面正如下一個問題所說的那樣在繼續之前只要做一兩次觀察
  
  Package Explorer 中顯示的元素和其它視圖(如 Outline 視圖)中顯示的相同元素之間有什麼關系?我們的擴展是否需要知道它們之間的任何區別?
  
  您可能已經注意到當您在 Outline 視圖和 Hierarchy 視圖中選擇了一個方法時所選對象的類並非總是相同的例如如果您在 Package Explorer 中展開一個庫(JAR 文件)的內容隨後選擇了一個類(或方法)那麼它也不會是 Java 編輯器的 Outline 視圖中同一選擇的那個類到底怎麼回事?
  
  這裡我們正在觀察 JDT 的 Java 模型中可編輯的部分和始終為只讀的部分之間的差別這兩部分 Java 模型都實現了公共接口(象 IMember)但是它們擁有用來理解底層限制的實現類是不同的另一個示例是有一個表示 Java 編譯單元的實現類它派生自 Package Explorer 所顯示的 JAR 文件的 class 文件還有另一個類表示直接派生自 java 文件的編譯單元後一個實現將允許進行一些前者所不允許的修改而它們 API 的共享部分是由接口 ICompilationUnit 表示的
  
  您以前在編輯 Java 源代碼時一定會觀察到在您輸入方法特征符時 Outline 視圖進行了更新(如果您沒有注意到那就試一下!)這個示例說明了 JDT 如何在不同的區域暫放其未提交的更改這與處理那些已保存編譯和集成到 Java 模型中的更改不同有些視圖(象 Java 編輯器的 Outline 視圖)知道未提交的更改和已提交的更改而其它象 Navigator 這樣的視圖只關心已保存到文件系統的已提交更改
  
  隨後我們所提供的用來修改 Java 成員的操作必須(至少在某種程度上)知道在什麼上下文中調用它它必須識別出某些所選成員是可修改的(那些位於 Java 編輯器的 Outline 視圖中的成員)而另一些成員是不可以修改的(存儲在 JAR 文件中以及顯示在 Package Explorer 中的 class 文件中的成員)記住這一點讓我們繼續下一個問題
  
  如何通過編程更改 JDT 模型?
  如果您在前面的旅行中稍作了研究那麼可能已經注意到 IMemberIJavaElement 以及我們的操作所看到的由所選的與 Java 相關的項實現的作為大部分接口的那部分都沒有 setXXX 方法那麼如何修改這些接口呢?
  
  您將發現這出奇地簡單不過可能在直覺上不那麼明顯JDT 的 Java 模型在大多數實踐情況下都是只讀通過與 Java 編譯器的集成協作給定元素的底層 Java 源代碼進行的更改就與 Java 模型的其余部分的更改同步了實際上您要做的就是更新 Java 源代碼而對模型所作的其余必要更改就傳送給任何依賴它們的元素中例如每當 Java 源代碼/Java 模型發生更改時JDT 的索引會自動更新所以仍舊可以快速執行搜索重新編譯從屬類(按照項目特性中指定的 Java 構建路徑所指示的)等等
  
  可以大松一口氣了!以下就是 Java 模型是插件集成之關鍵的原因所在Java 模型提供了整個 Java 環境的常見的內存中共享的模型它的范圍從一個項目一直到其所有被引用的庫所有這些都不要您費心去操作文件系統中的 java 文件class 文件以及 jar 文件您可以將精力集中於高級模型而讓 JDT 處理這其中的許多雜亂細節
  
  還不能確信它很容易?清單 包含了這個解決方案的核心代碼的一小部分它是從提供操作的 run 方法上抽取出的並出於可讀性考慮稍作了簡化
  
  清單 selectionChanged 方法小型解決方案
  
  public void selectionChanged(IAction action ISelection selection) {
   IMember member = (IMember)
     ((IStructuredSelection) selection)getFirstElement();
   ICompilationUnit cu = membergetCompilationUnit();
  
   if (cuisWorkingCopy()) {
    IBuffer buffer = cugetBuffer();
    bufferreplace();
    cureconcile();
   }
  }
  
  似乎有點虎頭蛇尾不是嗎?對您提供的操作提供了選中的成員向它請求其父容器(Java class 或 java 文件的模型用 JDT 的說法全都稱為編譯單元)因為其父容器管理底層源代碼驗證該成員是否屬於未提交的 Java 模型(換句話說它目前在編輯器中是打開的)然後修改作為緩沖器返回的源代碼IBuffer 接口類似於 StringBuffer其原理不同之處在於更改與編譯單元相關的緩沖區更新了 Java 模型的對應元素對 reconcile 的最終調用告知 JDT 去通知其它相關各方(象 Package Explorer 視圖)您的模型更新已准備好作為公共消費品
  
  您一定注意到上述代碼中的省略號在那裡您必須分析源代碼本身以進行修改同樣JDT 會提供幫助正如我們將在下一個問題中看到的
From:http://tw.wingwit.com/Article/program/Java/ky/201311/28006.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.