Eclipse插件開發之簡單控件封裝——那些年冗長的裹腳布
轉載本文需註明出處:微信公眾號EAWorld,違者必究。
Hello,大家好~不知道還有沒有老朋友記得我。
N年前那個寫流程自動化測試的程序媛就是我,可能看完那篇文章很多人認為我是自動化測試方向。
No,No,No~今天破案了,我真正的主要技術方向——Eclipse插件開發。是的,如此小眾的技術,有點疑惑都滿網找不到答案的技術。
思考了很久這塊可以寫點啥,基礎開發我也不多説了,願意看這篇文章的我也就默認已經是Eclipse插件開發入門了。
Eclipse插件開發,接觸過這塊的同學們都知道,無論是控件也好,嚮導視圖也罷。但凡每次開發個不起眼的小功能,從零開始堆代碼,都很煩躁,各種composite開始套,各種GridLayout佈局開始調。當你的公司要求你開發大量的插件功能時,可能多數的時間你都在堆砌這種煩躁的代碼。
在我司的EOS Platform裏封裝了進行了大量的swt封裝,今天我們就來説説其中最基礎的控件類封裝,即屬性編輯器。我們先來看下我們的UI框架。
每個Tab頁中我們進行了完整的對象編輯器的封裝,每個對象編輯器上,放置了多個屬性編輯器。
StringPropertyEditor就是一個屬性編輯器,ObjectEditor為一個對象編輯器,我們可以在一個ObjectEditor上添加多個StringPropertyEditor。
StringPropertyEditor基礎方法(不僅限於所展示的方法):
- setLabel(String label):標籤名稱。
- setPropertyName(String name):Text中value的數據映射key。
- doAddValidator(IValidator validator):添加校驗器。
這個時候我們是不是可以看出SWT控件開發和屬性編輯器開發的差異了?總結一下:
可以看下我們可以進行多少種不同的控件封裝。
看到類名大家應該差不多都清楚每個屬性編輯器的大體功能。我們就拿一個StringPropertyEditor看看它是如何封裝的吧。
StringPropertyEditorStringPropertyEditor就是Label+Text,例如:
1.首先它一定是先有一個對象屬性的基類AbstractPropertyAccessor,基類中的方法:
這個基類涉及到三個屬性:
- propertyName:value的數據映射key。
- element:默認為當前對象編輯器中的value對象,可給單個屬性編輯器設置單獨的value對象。But!該value對象中必須包含propertyName設置的key值。
- introspector:這是個什麼?這是個數據訪問接口對象Introspector。該接口定義瞭如何根據一個名稱(propertyName)來訪問一個對象(element)中的值。這樣設計為了提供靈活性,因為通常訪問數據有兩種方式。一種是根據Bean的屬性進行訪問,還有一種是使用Map中的Key進行訪問,所以設計這個接口來訪問對象中的數據,用户如果需要的話,也可以提供新的實現,如直接訪問對象的Field或者其它。簡單看下該接口的一個實現類所提供的方法。
通過Property的方式來訪問一個Bean對象,在Property 不存在的情況會拋出異常。對於對象的存儲用ognl.Ognl來實現。
2.AbstractPropertyAccessor基類只是提供了數據層的封裝,我們還需要一層封裝來提供屬性編輯器的基本實現AbstractPropertyEditor,這個類封裝了所有控件的佈局以及可能的操作。
其實這是相當長的一個封裝,抽取出核心事務,我們來説一説。
- 添加控件
這是一個核心的方法,你不需要去調用這個方法,在對象編輯器中的基類裏會自動調用來這個方法來繪製所有添加的屬性編輯器。
buildEditorControl創建用來編輯的SWT控件,即控件,控件的基本提示信息,控件的GridData,控件的錯誤信息的圖片等等。該方法中通過調用保護方法protected abstract IControlCreator createControlCreator()來獲取真實的子類控件。
getLayoutDataBuilder用來封裝控件的佈局,同樣,子類可以通過重構來改變自己的佈局。
這個方法同樣是對控件的處理,之所以同控件的添加分開,是因為這個方法中的操作並不是每個控件必須的,根據需要繼承開發。這個封裝方法中做了兩件事,一個是binding,也就是處理控件的聯動,這裏封裝了控件的屬性值綁定聯動,以及反向綁定的聯動處理。另一個就是為當前的編輯控件增加焦點監聽器。
- 動態更改控制值
這個方法除了在load的時候會調用,在對象編輯器使用的過程中,控件的聯動也會使用到,比如最常見到的,瀏覽資源,點擊瀏覽的button彈出資源選擇框,根據選中的對象回填對象編輯器中的值,就會用到該方法。在這個setValue方法中,是通過數據改變的封裝接口去實現的。我們可以看下這個數據改變的容器接口。
其中fireValueChanged(ValueChangeEvent r_Event)就是調用所有的值監聽器,通知當前控件的值已經改變。所以不同的對象編輯器之間都可以使用這個fireValueChanged來進行數據的聯動處理。
- 容器佈局
在build方法中我們簡單提到了getLayoutDataBuilder獲取佈局,這個方法獲取的佈局類GridLayoutDataBuilder,同樣是我們經過封裝。
可以看到,在這個類裏,我們已經對佈局進行了一系列初始的封裝,除非有特殊的佈局需求,可以調用其中的方法更改佈局,其他大部分的場景默認佈局已經可以滿足。
這就是對象屬性的基類AbstractPropertyAccessor的核心處理,還有很多方法的封裝都是可以根據用户的需要自行定義,當然根據控件有需要的可以再封裝一層包含各類監聽接口的基類,例如:KeyListener, FocusListener, SelectionListener, ModifyListener等。
3.説完了基類,StringPropertyEditor就變得簡單了。
值得説一下的就是文本框的繪製方法了。
因為這裏用到了文本框的封裝,我們來看下文本框的封裝。
做的事很簡單,將固定樣式的Text放入到我們的屬性編輯器上,並且增加Modify的監聽。除此之外我們還有對其他單個控件的封裝。
至此,我們一個屬性編輯器就開發完成了。
下面我們看看對象編輯器ObjectEditor的封裝。
ObjectEditor根據對象編輯器和屬性編輯器的關係,不難理解,對象編輯器就是對屬性編輯器的加載、放置、佈局。核心方法build,就是遍歷調用屬性編輯器的繪製。
這是一個一目瞭然的方法,對象編輯器中的其他操作方法亦是如此,都是遍歷屬性編輯器,對屬性編輯器的挨個操作。
好了,我們完成了控件的封裝,是不是覺得封裝方法略多,好麻煩啊,我還是複製複製代碼,一個個控件添加好了。
But!複雜的封裝是一時的,日後便利的開發是永久的!
然後你又要問了,那麼我們封裝好了對象編輯器又如何,我們也放不到Wizard放不到View上啊。
So
下一期我們來説説
各種讓我們掛上對象編輯器的控件工廠吧~
劇透圖
關於作者:leaf淼,普元高級軟件工程師,善於Studio插件的開發與設計,目前負責EOS/BPS Studio產品開發,曾參與浦發銀行BPM流程產品開發、太平洋保險集團微服務平台開發等。
關於EAWorld:微服務,DevOps,數據治理,移動架構原創技術分享。
【來源:EAWorld】
聲明:轉載此文是出於傳遞更多信息之目的。若有來源標註錯誤或侵犯了您的合法權益,請作者持權屬證明與本網聯繫,我們將及時更正、刪除,謝謝。 郵箱地址:newmedia@xxcb.cn