繼之前曾經提到,關於要載入的class假設是存在於另外一個plugin時,當下啟用應用時若沒有
勾選該plugin,如此一來catch exception時會繼續執行另一resource。在這邊將另外提到Eclipse
plugin的一個很重要的技術Extension point and extension,相信在.plugin內的頁籤您曾經設定過
Extensions,如之前有建立Preferences,當下會引入org.eclipse.ui.PreferencesPages 、
org.eclipse.core.runtime.preferences(Extension point),此時有相關的欄位需要我們填寫,
當下我們就是在擴充Preferences的功能(建立Extensions),因此執行應用後可以在Preferences
頁面內見到我們所定義的item!
相關概念如下圖:
也就是說,假設我將extensions內所定義的extension刪除掉,重新執行應用的話,Preferences內
首先,我們在com.bin.practice.ui plugin內定義extension point,如下:
勾選該plugin,如此一來catch exception時會繼續執行另一resource。在這邊將另外提到Eclipse
plugin的一個很重要的技術Extension point and extension,相信在.plugin內的頁籤您曾經設定過
Extensions,如之前有建立Preferences,當下會引入org.eclipse.ui.PreferencesPages 、
org.eclipse.core.runtime.preferences(Extension point),此時有相關的欄位需要我們填寫,
當下我們就是在擴充Preferences的功能(建立Extensions),因此執行應用後可以在Preferences
頁面內見到我們所定義的item!
相關概念如下圖:
圖片來源 - Vogella
就不會有我所定義的items了!
因此,在這裡我將要自行定義extension point,並且在另外一個plugin內建立extension,如此
一來一樣可以達到上一篇文章Eclipse Plug-in - Dynamic load other bundle's class所要的目的!
與該篇文章一樣,首先我們所開啟的頁面一樣是定義在plugin - com.bin.practice.ui內
而我們將在com.bin.practice.prefs內建立我們自訂的extension!
PS. 關於Extension point and extension的說明與定義可以參考Vogella
一、建立extension point
首先,我們在com.bin.practice.ui plugin內定義extension point,如下:
Extension Point ID and Extension Point Name好比註冊的識別碼,只要在同一個應用內的所有
plugin有使用到這個ID與Name所建立的extension! 之後都可以在程式內搜尋的到!
之後會自動跳到定義頁面,至Definition定義這個extension在建立時需要填寫那些欄位
在此定義一element - dialogDefine
欄位分別為 id, dialog_name, dialog_instance,在此除了前兩項為string type外
最後一項為一指定class
緊接著,在extension下建立一Sequence,並在其下建立剛剛所定義的element - dialogDefine
二、建立extension
extension point建立好之後,再來按照範例就是在plugin - com.bin.practice.prefs內建立之
如此一來,執行下面這兩段code一樣可以達到初始化dialog的目的
dialog.setShell(formBody.getShell());
dialog.setDialogItem(t[0].getText());
而在取得dialog_instance的實體之後為什麼要轉型成IDialog?
因為如此一來才可以在沒有import MessageDialogTest不會有編譯錯誤
即假設今天在執行應用程式時沒有load com.bin.practice.prefs
這一種情境,程式將不會進入迴圈,opened => false,將執行的會是TitleAreaDialogTest
若有load com.bin.practice.prefs,程式將執行的會是MessageDialogTest
再來請回到plugin - com.bin.practice.ui
至MyFormPage.java檔案內修改,關於這個檔案的程式可參照下面連結
這邊主要是修改tree addSelectionListener事件處理
tree.addSelectionListener(new SelectionListener(){
@Override
public void widgetSelected(SelectionEvent e) {
// TODO Auto-generated method stub
Tree element = (Tree) e.getSource();
TreeItem[] t = element.getSelection();
boolean opened = false;
if(t != null && t.length > 0 && treeMap.containsKey(t[0].getText())){
IExtensionRegistry registory = Platform.getExtensionRegistry();
IExtensionPoint extensionPoint = registory.getExtensionPoint(Activator.PLUGIN_ID, "dialog");
IConfigurationElement[] exts = extensionPoint.getConfigurationElements();
for(IConfigurationElement ext : exts){
try {
opened = true;
IDialog dialog = (IDialog) ext.createExecutableExtension("dialog_instance");
dialog.setShell(formBody.getShell());
dialog.setDialogItem(t[0].getText());
dialog.open();
} catch (CoreException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
if(!opened){
TitleAreaDialogTest dialog = new TitleAreaDialogTest(formBody.getShell(), t[0].getText());
dialog.open();
}
}
}
@Override
public void widgetDefaultSelected(SelectionEvent e) {
// TODO Auto-generated method stub
}
});
請注意,registrory.getExtensionPoint()內需指定該extension point's
ID分成namespace => com.bin.practice.ui, simple identifier => dialog
再過來extensionPoint.getConfigurationElements()可以取得所有plugin有建立
extensions's elements。最後則是進行走訪來取得dialog_instance欄位的實體(class type)
接著,由於當您取得dialog_instance的實體時,程式並無法進行MessageDialogTest constructor
的呼叫來初始化! 以Eclipse Plug-in - Dynamic load other bundle's class的作法是如下取得實體
Object object = constr[0].newInstance(formBody.getShell(), t[0].getText()); 會帶入兩個參數進去
因此在這邊,我們將重新調整一下extension point的設定
首先建立一interface - IDialog.java
public interface IDialog {
public void setShell(Shell shell);
public void setDialogItem(String item);
public int open();
}
再來是調整MessageDialogTest implements IDialog,並且override相關method
@Override
public int open(){
return super.open();
}
@Override
public void setShell(Shell shell) {
// TODO Auto-generated method stub
configureShell(shell);
}
@Override
public void setDialogItem(String item) {
// TODO Auto-generated method stub
this.item = item;
}
如此一來,執行下面這兩段code一樣可以達到初始化dialog的目的
dialog.setShell(formBody.getShell());
dialog.setDialogItem(t[0].getText());
而在取得dialog_instance的實體之後為什麼要轉型成IDialog?
因為如此一來才可以在沒有import MessageDialogTest不會有編譯錯誤
即假設今天在執行應用程式時沒有load com.bin.practice.prefs
這一種情境,程式將不會進入迴圈,opened => false,將執行的會是TitleAreaDialogTest
若有load com.bin.practice.prefs,程式將執行的會是MessageDialogTest
留言
張貼留言