【Eclipse插件開發(fā)】基于WTP開發(fā)自定義的JSP編輯器(四):Strucutured Document分析視圖
在上一篇中,我們詳細(xì)闡述了WTP中最重要的數(shù)據(jù)模型之一IStructuredDocument(我們就稱之為WTP Document吧,和另外一個核心數(shù)據(jù)模型WTP Model----IStructuredModel對應(yīng)),本節(jié)中我們將自己開發(fā)一個工具來分析IStrucutredDocument。
PS:千萬別著急,后面的文章會對WTP StructuredTextEditor進行功能特征定制的,在真正定制之前一定要搞清楚WTP Document(IStructuredDocument)和WTP Model(IStructuredModel),連核心數(shù)據(jù)模型都不熟悉,后面談何定制^_^
【W(wǎng)TP提供的Properteis視圖擴展】
說明:Properteis視圖是Eclipse固有的,允許用戶通過相應(yīng)的類型擴展機制來定制Properties視圖中的內(nèi)容,涉及到的主要知識點包括:
1、Eclipse的Adapter機制(IAdaptable、IAdapterFactory、AdapterManager),關(guān)于Eclipse中的類型適配擴展機制,博客中的另外一篇文章做了分析:
【Eclipse插件開發(fā)】Eclipse中類型擴展機制分析
2、Properties視圖相關(guān)的幾個重要接口:
org.eclipse.ui.views.properties.IPropertySource.class
org.eclipse.ui.views.properties.PropertySheetPage
...
3、WTP就是借助于Eclipse類型擴展機制,實現(xiàn)了對應(yīng)的功能。我們看一下在WTP的StructuredTextEditor中的getAdapter方法中提供了擴展服務(wù)(IWorkbenchPart本身就是聲明為IAdaptable):
WTP的properties視圖的主要功能就是,根據(jù)用戶在編輯器中光標(biāo)的位置,在Properties視圖中展示對應(yīng)的標(biāo)簽內(nèi)容,并支持用戶編輯,例如:

當(dāng)前編輯器中,用戶光標(biāo)位于jsp:directive.page標(biāo)簽內(nèi),屬性視圖就列舉了對應(yīng)的標(biāo)簽內(nèi)容,允許用戶編輯。
【我們自己的Stuctured Document View】
如果有一個視圖來將當(dāng)前編輯器中的內(nèi)容對應(yīng)的IStrucuturedDocument以樹狀結(jié)構(gòu)的方式展示出來,再提供一定的用戶交互,那對認(rèn)清楚IStructuredDocument的本質(zhì)是有作用的哈
【需求】
1、提供一個Structured Document View視圖,以樹狀方式將當(dāng)前編輯器中的IStructuredDocument展示出來
2、交互(編輯器 ---> Structured Document View視圖):
激活WTP JSP編輯器(或者是我們前面自己定制的編輯器),即時更新Structured Document View視圖
當(dāng)用戶光在編輯器中標(biāo)移動時,自動選中Structured Document View視圖中對應(yīng)的節(jié)點
當(dāng)編輯器中的內(nèi)容改變時,即時更新Structured Document View視圖
當(dāng)前激活編輯器關(guān)閉時,清空Structured Document View視圖內(nèi)容
3、交互(Structured Document View視圖 ---> 編輯器)
雙擊視圖中樹狀控件中特定節(jié)點,對應(yīng)內(nèi)容在編輯器中被選中
4、顯示內(nèi)容:
對于IStructuredDocument,則顯示對應(yīng)的具體實現(xiàn)類(對應(yīng)于JSP類型則為JobSafeStructuredDocument)
對于IStrucutredDocumentRegion(ITextRegionCollection),則顯示實現(xiàn)類名稱、節(jié)點類型、位置范圍、文本等
對于葉子節(jié)點的ITextRegion,則顯示實現(xiàn)類名稱、節(jié)點類型、位置范圍(說明:相對于父ITextRegionCollection的相對位置,非對于整個文檔的相對位置!!!)
【效果預(yù)覽】

如上圖所示,雙擊視圖中的節(jié)點,編輯器中對應(yīng)的內(nèi)容被選中^_^。
【實現(xiàn)摘要(文章后面會附上完整代碼)】
1、創(chuàng)建插件工程wtp.stuctureddocument,創(chuàng)建視圖,不用多說,利用擴展點org.eclipse.ui.views,對應(yīng)內(nèi)容如下:
2、利用workbench中的選擇服務(wù)(seleciton service)。前面需求中說過,我們要監(jiān)聽光標(biāo)在編輯器中的位置選擇,所以使用此服務(wù),所以我們的StructuredDocumentView要實現(xiàn)org.eclipse.ui.ISelectionListener接口。
(PS:selection service是workbench的一個重要特性,也是我們常用的,Eclipse官方網(wǎng)站上有一篇專題文章,看看撒兩眼^_^)
注冊selection listener:
實現(xiàn)selection事件處理:
看的出來,我們的selection處理邏輯如下:
1、如果當(dāng)前選擇事件來自TextEditor類型的編輯器中(文本編輯器的共同超類),則去獲取編輯器對應(yīng)的IDocument,如果是IStrucuturedDocument則判斷是否需要更新;如果不是,則不是我們的目標(biāo)(例如如果打開的是java源碼編輯器,那對應(yīng)的IDocument實現(xiàn)肯定不是WTP的IStrucuturedDocument了哈^_^)
2、如果是IStrucuturedDocument,則確定是否需要更新(也就是判斷我們的Structured Document分析視圖中現(xiàn)有的input是否就是當(dāng)前編輯器中內(nèi)容對應(yīng)的IStrucuturedDocument)。如果需要更新,則重新設(shè)置tree viewer輸入
3、我們根據(jù)光標(biāo)在編輯器中的位置信息(參加org.eclipse.jface.text.ITexSelection),首先利用IStructuredDocument.getRegionAtCharacterOffset(int)來定位對應(yīng)的IStructuredDocumentRegion樹枝節(jié)點,然后在利用IStructuredDocumentRegion.getRegionAtCharacterOffset(int)來定位對應(yīng)的ITextRegion樹葉節(jié)點,在我們視圖的樹狀控件中選中對應(yīng)的樹葉節(jié)點。
回顧:對于IStructuredDocument來說,它的孩子就是IStructuredDoucmentRegion,并沒有提供對應(yīng)的接口允許用戶直接去獲取特定offset對應(yīng)的具體ITextRegion。再看一下前面用到的一幅圖吧:

3、處理視圖中tree viewer雙擊,定位編輯器中對應(yīng)內(nèi)容。
4、利用IDocumentListener同步更新視圖。邏輯非常簡單,如下:
注意:我們這邊并沒有wtp自己的document listener,它自己都不建議使用了^_^
5、處理編輯器關(guān)閉行為,利用workbench的part service特性。當(dāng)對應(yīng)的編輯器關(guān)閉時,視圖中的tree viewer
注冊代碼再上面的init方法代碼中有,注冊了對應(yīng)的selection listener和part listener
上面基本上就是我們的視圖主類wtp.structureddocument.view.StructuredDocumentView的所有代碼了,我們開發(fā)這樣一個視圖也只用了200多行代碼...
最后強調(diào)一下,我們的這個插件工程需要依賴的插件列表為:
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.wst.sse.core,
org.eclipse.wst.xml.core,
org.eclipse.wst.sse.ui,
org.eclipse.jface.text,
org.eclipse.ui.workbench.texteditor
【源碼下載】
源碼為實際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:source.zip 。
PS:千萬別著急,后面的文章會對WTP StructuredTextEditor進行功能特征定制的,在真正定制之前一定要搞清楚WTP Document(IStructuredDocument)和WTP Model(IStructuredModel),連核心數(shù)據(jù)模型都不熟悉,后面談何定制^_^
【W(wǎng)TP提供的Properteis視圖擴展】
說明:Properteis視圖是Eclipse固有的,允許用戶通過相應(yīng)的類型擴展機制來定制Properties視圖中的內(nèi)容,涉及到的主要知識點包括:
1、Eclipse的Adapter機制(IAdaptable、IAdapterFactory、AdapterManager),關(guān)于Eclipse中的類型適配擴展機制,博客中的另外一篇文章做了分析:
【Eclipse插件開發(fā)】Eclipse中類型擴展機制分析
2、Properties視圖相關(guān)的幾個重要接口:
org.eclipse.ui.views.properties.IPropertySource.class
org.eclipse.ui.views.properties.PropertySheetPage
...
3、WTP就是借助于Eclipse類型擴展機制,實現(xiàn)了對應(yīng)的功能。我們看一下在WTP的StructuredTextEditor中的getAdapter方法中提供了擴展服務(wù)(IWorkbenchPart本身就是聲明為IAdaptable):
1 /*
2 * (non-Javadoc)
3 *
4 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
5 */
6 public Object getAdapter(Class required) {
7 //
8 else if (IPropertySheetPage.class.equals(required) && isEditable()) {
9 if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) {
10 PropertySheetConfiguration cfg = createPropertySheetConfiguration();
11 if (cfg != null) {
12 ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage();
13 propertySheetPage.setConfiguration(cfg);
14 fPropertySheetPage = propertySheetPage;
15 }
16 }
17 result = fPropertySheetPage;
18 }
19 //
.
20 }
ConfigurablePropertySheetPage^_^(org.eclipse.wst.sse.ui.internal.properties.ConfigurablePropertySheetPage)。2 * (non-Javadoc)
3 *
4 * @see org.eclipse.core.runtime.IAdaptable#getAdapter(java.lang.Class)
5 */
6 public Object getAdapter(Class required) {
7 //

8 else if (IPropertySheetPage.class.equals(required) && isEditable()) {
9 if (fPropertySheetPage == null || fPropertySheetPage.getControl() == null || fPropertySheetPage.getControl().isDisposed()) {
10 PropertySheetConfiguration cfg = createPropertySheetConfiguration();
11 if (cfg != null) {
12 ConfigurablePropertySheetPage propertySheetPage = new ConfigurablePropertySheetPage();
13 propertySheetPage.setConfiguration(cfg);
14 fPropertySheetPage = propertySheetPage;
15 }
16 }
17 result = fPropertySheetPage;
18 }
19 //

20 }
WTP的properties視圖的主要功能就是,根據(jù)用戶在編輯器中光標(biāo)的位置,在Properties視圖中展示對應(yīng)的標(biāo)簽內(nèi)容,并支持用戶編輯,例如:
當(dāng)前編輯器中,用戶光標(biāo)位于jsp:directive.page標(biāo)簽內(nèi),屬性視圖就列舉了對應(yīng)的標(biāo)簽內(nèi)容,允許用戶編輯。
【我們自己的Stuctured Document View】
如果有一個視圖來將當(dāng)前編輯器中的內(nèi)容對應(yīng)的IStrucuturedDocument以樹狀結(jié)構(gòu)的方式展示出來,再提供一定的用戶交互,那對認(rèn)清楚IStructuredDocument的本質(zhì)是有作用的哈
【需求】
1、提供一個Structured Document View視圖,以樹狀方式將當(dāng)前編輯器中的IStructuredDocument展示出來
2、交互(編輯器 ---> Structured Document View視圖):
激活WTP JSP編輯器(或者是我們前面自己定制的編輯器),即時更新Structured Document View視圖
當(dāng)用戶光在編輯器中標(biāo)移動時,自動選中Structured Document View視圖中對應(yīng)的節(jié)點
當(dāng)編輯器中的內(nèi)容改變時,即時更新Structured Document View視圖
當(dāng)前激活編輯器關(guān)閉時,清空Structured Document View視圖內(nèi)容
3、交互(Structured Document View視圖 ---> 編輯器)
雙擊視圖中樹狀控件中特定節(jié)點,對應(yīng)內(nèi)容在編輯器中被選中
4、顯示內(nèi)容:
對于IStructuredDocument,則顯示對應(yīng)的具體實現(xiàn)類(對應(yīng)于JSP類型則為JobSafeStructuredDocument)
對于IStrucutredDocumentRegion(ITextRegionCollection),則顯示實現(xiàn)類名稱、節(jié)點類型、位置范圍、文本等
對于葉子節(jié)點的ITextRegion,則顯示實現(xiàn)類名稱、節(jié)點類型、位置范圍(說明:相對于父ITextRegionCollection的相對位置,非對于整個文檔的相對位置!!!)
【效果預(yù)覽】
如上圖所示,雙擊視圖中的節(jié)點,編輯器中對應(yīng)的內(nèi)容被選中^_^。
【實現(xiàn)摘要(文章后面會附上完整代碼)】
1、創(chuàng)建插件工程wtp.stuctureddocument,創(chuàng)建視圖,不用多說,利用擴展點org.eclipse.ui.views,對應(yīng)內(nèi)容如下:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <?eclipse version="3.2"?>
3 <plugin>
4 <extension
5 point="org.eclipse.ui.views">
6 <category
7 id="wtp.structureddocument.category"
8 name="Structured Document分析"/>
9 <view
10 category="wtp.structureddocument.category"
11 class="wtp.structureddocument.view.StructuredDocumentView"
12 id="wtp.structureddocument.view"
13 name="Structured Document分析"/>
14 </extension>
15 </plugin>
wtp.structureddocument.view.StructuredDocumentView為視圖對應(yīng)的ViewPart實現(xiàn),里面創(chuàng)建了一個tree viewer控件,并給其配置了對應(yīng)的content provider和label provider,具體參加附件中的源碼。2 <?eclipse version="3.2"?>
3 <plugin>
4 <extension
5 point="org.eclipse.ui.views">
6 <category
7 id="wtp.structureddocument.category"
8 name="Structured Document分析"/>
9 <view
10 category="wtp.structureddocument.category"
11 class="wtp.structureddocument.view.StructuredDocumentView"
12 id="wtp.structureddocument.view"
13 name="Structured Document分析"/>
14 </extension>
15 </plugin>
2、利用workbench中的選擇服務(wù)(seleciton service)。前面需求中說過,我們要監(jiān)聽光標(biāo)在編輯器中的位置選擇,所以使用此服務(wù),所以我們的StructuredDocumentView要實現(xiàn)org.eclipse.ui.ISelectionListener接口。
(PS:selection service是workbench的一個重要特性,也是我們常用的,Eclipse官方網(wǎng)站上有一篇專題文章,看看撒兩眼^_^)
注冊selection listener:
1 /* (non-Javadoc)
2 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
3 */
4 public void init(IViewSite site) throws PartInitException {
5 super.init(site);
6
7 this.getSite().getPage().getWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
8 this.getSite().getPage().getWorkbenchWindow().getPartService().addPartListener(partListener);
9 }
2 * @see org.eclipse.ui.part.ViewPart#init(org.eclipse.ui.IViewSite)
3 */
4 public void init(IViewSite site) throws PartInitException {
5 super.init(site);
6
7 this.getSite().getPage().getWorkbenchWindow().getSelectionService().addPostSelectionListener(this);
8 this.getSite().getPage().getWorkbenchWindow().getPartService().addPartListener(partListener);
9 }
實現(xiàn)selection事件處理:
1 /* (non-Javadoc)
2 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
3 */
4 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
5 if (part instanceof TextEditor) {
6 IEditorInput editorInput = ((TextEditor)part).getEditorInput();
7 IDocument document = ((TextEditor)part).getDocumentProvider().getDocument(editorInput);
8
9 if (!(document instanceof IStructuredDocument)) {
10 this.viewer.setInput(new Object[0]);
11 return ;
12 }
13
14 IStructuredDocument structuredDocument = (IStructuredDocument)document;
15
16 if (this.needUpdateInput(document)) {
17 this.viewer.setInput(new Object[]{document});
18 this.viewer.expandAll();
19 this.viewer.collapseAll();
20
21 //set source workbench part, will be used in part listener
22 this.sourcePart = part;
23
24 //注冊監(jiān)聽器,便于同步刷新tree viewer
25 structuredDocument.addDocumentListener(documentListener);
26 }
27
28 if (selection instanceof ITextSelection) {
29 int offset = ((ITextSelection)selection).getOffset();
30 IStructuredDocumentRegion structuredDocumentRegion = structuredDocument.getRegionAtCharacterOffset(offset);
31 ITextRegion textRegion = structuredDocumentRegion.getRegionAtCharacterOffset(offset);
32
33 this.viewer.collapseAll();
34 this.viewer.expandToLevel(structuredDocumentRegion, 2);
35 this.viewer.setSelection(new StructuredSelection(textRegion));
36 }
37 }
38 }
2 * @see org.eclipse.ui.ISelectionListener#selectionChanged(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
3 */
4 public void selectionChanged(IWorkbenchPart part, ISelection selection) {
5 if (part instanceof TextEditor) {
6 IEditorInput editorInput = ((TextEditor)part).getEditorInput();
7 IDocument document = ((TextEditor)part).getDocumentProvider().getDocument(editorInput);
8
9 if (!(document instanceof IStructuredDocument)) {
10 this.viewer.setInput(new Object[0]);
11 return ;
12 }
13
14 IStructuredDocument structuredDocument = (IStructuredDocument)document;
15
16 if (this.needUpdateInput(document)) {
17 this.viewer.setInput(new Object[]{document});
18 this.viewer.expandAll();
19 this.viewer.collapseAll();
20
21 //set source workbench part, will be used in part listener
22 this.sourcePart = part;
23
24 //注冊監(jiān)聽器,便于同步刷新tree viewer
25 structuredDocument.addDocumentListener(documentListener);
26 }
27
28 if (selection instanceof ITextSelection) {
29 int offset = ((ITextSelection)selection).getOffset();
30 IStructuredDocumentRegion structuredDocumentRegion = structuredDocument.getRegionAtCharacterOffset(offset);
31 ITextRegion textRegion = structuredDocumentRegion.getRegionAtCharacterOffset(offset);
32
33 this.viewer.collapseAll();
34 this.viewer.expandToLevel(structuredDocumentRegion, 2);
35 this.viewer.setSelection(new StructuredSelection(textRegion));
36 }
37 }
38 }
1 /**
2 * 判斷當(dāng)前document和tree viewer中輸入的document是否一致
3 *
4 * @param document
5 * @return
6 */
7 private boolean needUpdateInput(IDocument document) {
8 if (this.viewer.getInput() != null) {
9 Object[] oldInput = (Object[])this.viewer.getInput();
10 if (oldInput.length == 1)
11 return oldInput[0] != document;
12 }
13
14 return true;
15 }
2 * 判斷當(dāng)前document和tree viewer中輸入的document是否一致
3 *
4 * @param document
5 * @return
6 */
7 private boolean needUpdateInput(IDocument document) {
8 if (this.viewer.getInput() != null) {
9 Object[] oldInput = (Object[])this.viewer.getInput();
10 if (oldInput.length == 1)
11 return oldInput[0] != document;
12 }
13
14 return true;
15 }
看的出來,我們的selection處理邏輯如下:
1、如果當(dāng)前選擇事件來自TextEditor類型的編輯器中(文本編輯器的共同超類),則去獲取編輯器對應(yīng)的IDocument,如果是IStrucuturedDocument則判斷是否需要更新;如果不是,則不是我們的目標(biāo)(例如如果打開的是java源碼編輯器,那對應(yīng)的IDocument實現(xiàn)肯定不是WTP的IStrucuturedDocument了哈^_^)
2、如果是IStrucuturedDocument,則確定是否需要更新(也就是判斷我們的Structured Document分析視圖中現(xiàn)有的input是否就是當(dāng)前編輯器中內(nèi)容對應(yīng)的IStrucuturedDocument)。如果需要更新,則重新設(shè)置tree viewer輸入
3、我們根據(jù)光標(biāo)在編輯器中的位置信息(參加org.eclipse.jface.text.ITexSelection),首先利用IStructuredDocument.getRegionAtCharacterOffset(int)來定位對應(yīng)的IStructuredDocumentRegion樹枝節(jié)點,然后在利用IStructuredDocumentRegion.getRegionAtCharacterOffset(int)來定位對應(yīng)的ITextRegion樹葉節(jié)點,在我們視圖的樹狀控件中選中對應(yīng)的樹葉節(jié)點。
回顧:對于IStructuredDocument來說,它的孩子就是IStructuredDoucmentRegion,并沒有提供對應(yīng)的接口允許用戶直接去獲取特定offset對應(yīng)的具體ITextRegion。再看一下前面用到的一幅圖吧:
3、處理視圖中tree viewer雙擊,定位編輯器中對應(yīng)內(nèi)容。
1 this.viewer.addDoubleClickListener(new IDoubleClickListener() {
2 public void doubleClick(DoubleClickEvent event) {
3 TreeSelection treeSelection = (TreeSelection)event.getSelection();
4 TreePath treePath = treeSelection.getPaths()[0];
5
6 if (treePath.getSegmentCount() == 1) {
7 //選擇的是IStructuredDocument
8 IStructuredDocument structuredDocument = (IStructuredDocument)treeSelection.getFirstElement();
9
10 //處理編輯器選中,選中整個文檔
11 ((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(0, structuredDocument.getLength());
12 }
13 else if (treePath.getSegmentCount() == 2) {
14 //選擇的是IStructuredDocumentRegion
15 IStructuredDocumentRegion structuredDocumentRegion = (IStructuredDocumentRegion)treePath.getLastSegment();
16 int selectionOffset = structuredDocumentRegion.getStart();
17 int selectionLength = structuredDocumentRegion.getLength();
18
19 //處理編輯器選中,選中structured document region區(qū)域
20 ((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(selectionOffset, selectionLength);
21 }
22 else if (treePath.getSegmentCount() == 3) {
23 //選擇的是非container的ITextRegion,其父節(jié)點為IStructuredDocumentRegion
24 IStructuredDocumentRegion structuredDocumentRegion = (IStructuredDocumentRegion)treePath.getSegment(1);
25 ITextRegion textRegion = (ITextRegion)treePath.getLastSegment();
26
27 int selectionOffset = structuredDocumentRegion.getStartOffset(textRegion);
28 int selectionLength = textRegion.getLength();
29
30 //處理編輯器選中,選中的是葉子節(jié)點的text region區(qū)域
31 ((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(selectionOffset, selectionLength);
32 }
33 }
34 });
TreePath(org.eclipse.jface.viewers.TreePath)中的seg count信息其實確定了我們的雙擊的控件位于整個樹狀控件的位置,具體自己看吧^_^2 public void doubleClick(DoubleClickEvent event) {
3 TreeSelection treeSelection = (TreeSelection)event.getSelection();
4 TreePath treePath = treeSelection.getPaths()[0];
5
6 if (treePath.getSegmentCount() == 1) {
7 //選擇的是IStructuredDocument
8 IStructuredDocument structuredDocument = (IStructuredDocument)treeSelection.getFirstElement();
9
10 //處理編輯器選中,選中整個文檔
11 ((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(0, structuredDocument.getLength());
12 }
13 else if (treePath.getSegmentCount() == 2) {
14 //選擇的是IStructuredDocumentRegion
15 IStructuredDocumentRegion structuredDocumentRegion = (IStructuredDocumentRegion)treePath.getLastSegment();
16 int selectionOffset = structuredDocumentRegion.getStart();
17 int selectionLength = structuredDocumentRegion.getLength();
18
19 //處理編輯器選中,選中structured document region區(qū)域
20 ((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(selectionOffset, selectionLength);
21 }
22 else if (treePath.getSegmentCount() == 3) {
23 //選擇的是非container的ITextRegion,其父節(jié)點為IStructuredDocumentRegion
24 IStructuredDocumentRegion structuredDocumentRegion = (IStructuredDocumentRegion)treePath.getSegment(1);
25 ITextRegion textRegion = (ITextRegion)treePath.getLastSegment();
26
27 int selectionOffset = structuredDocumentRegion.getStartOffset(textRegion);
28 int selectionLength = textRegion.getLength();
29
30 //處理編輯器選中,選中的是葉子節(jié)點的text region區(qū)域
31 ((StructuredTextEditor)sourcePart).getTextViewer().setSelectedRange(selectionOffset, selectionLength);
32 }
33 }
34 });
4、利用IDocumentListener同步更新視圖。邏輯非常簡單,如下:
1 private class StructuredDocumentListener implements IDocumentListener {
2 public void documentChanged(DocumentEvent event) {
3 viewer.refresh();
4 }
5
6 public void documentAboutToBeChanged(DocumentEvent event) {
7 // nothing to do
8 }
9 }
我們的listener實在前面handle selection的過程注冊的,再決定用一個新的IStructuredDocument作為tree viewer輸入的時候,同步注冊對應(yīng)的監(jiān)聽器。2 public void documentChanged(DocumentEvent event) {
3 viewer.refresh();
4 }
5
6 public void documentAboutToBeChanged(DocumentEvent event) {
7 // nothing to do
8 }
9 }
注意:我們這邊并沒有wtp自己的document listener,它自己都不建議使用了^_^
5、處理編輯器關(guān)閉行為,利用workbench的part service特性。當(dāng)對應(yīng)的編輯器關(guān)閉時,視圖中的tree viewer
1 private class PartListener implements IPartListener {
2 public void partActivated(IWorkbenchPart part) {
3 // TODO Auto-generated method stub
4
5 }
6
7 public void partBroughtToTop(IWorkbenchPart part) {
8 // TODO Auto-generated method stub
9
10 }
11
12 /*
13 * 如果被關(guān)閉的workbench part是提供document信息的source part,則情況tree viewer
14 *
15 * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
16 */
17 public void partClosed(IWorkbenchPart part) {
18 if (sourcePart == part) {
19 sourcePart = null;
20 viewer.setInput(new Object[0]);
21 }
22 }
23
24 public void partDeactivated(IWorkbenchPart part) {
25 // TODO Auto-generated method stub
26
27 }
28
29 public void partOpened(IWorkbenchPart part) {
30 // TODO Auto-generated method stub
31 }
32 }
注意:上面代碼的source part是我們的handle selection過程中緩存的,這邊就派上用場了啊,能夠判斷當(dāng)前關(guān)閉的part是否就提供當(dāng)前IStructuredDocument的text eidtor 了^_^2 public void partActivated(IWorkbenchPart part) {
3 // TODO Auto-generated method stub
4
5 }
6
7 public void partBroughtToTop(IWorkbenchPart part) {
8 // TODO Auto-generated method stub
9
10 }
11
12 /*
13 * 如果被關(guān)閉的workbench part是提供document信息的source part,則情況tree viewer
14 *
15 * @see org.eclipse.ui.IPartListener#partClosed(org.eclipse.ui.IWorkbenchPart)
16 */
17 public void partClosed(IWorkbenchPart part) {
18 if (sourcePart == part) {
19 sourcePart = null;
20 viewer.setInput(new Object[0]);
21 }
22 }
23
24 public void partDeactivated(IWorkbenchPart part) {
25 // TODO Auto-generated method stub
26
27 }
28
29 public void partOpened(IWorkbenchPart part) {
30 // TODO Auto-generated method stub
31 }
32 }
注冊代碼再上面的init方法代碼中有,注冊了對應(yīng)的selection listener和part listener
上面基本上就是我們的視圖主類wtp.structureddocument.view.StructuredDocumentView的所有代碼了,我們開發(fā)這樣一個視圖也只用了200多行代碼...
最后強調(diào)一下,我們的這個插件工程需要依賴的插件列表為:
org.eclipse.ui,
org.eclipse.core.runtime,
org.eclipse.core.resources,
org.eclipse.wst.sse.core,
org.eclipse.wst.xml.core,
org.eclipse.wst.sse.ui,
org.eclipse.jface.text,
org.eclipse.ui.workbench.texteditor
【源碼下載】
源碼為實際工程以Export ---> Archive File方式導(dǎo)出的,下載鏈接:source.zip 。
本博客中的所有文章、隨筆除了標(biāo)題中含有引用或者轉(zhuǎn)載字樣的,其他均為原創(chuàng)。轉(zhuǎn)載請注明出處,謝謝!
posted on 2008-09-11 16:16 zhuxing 閱讀(3183) 評論(3) 編輯 收藏 所屬分類: Eclipse Plug-in & OSGI 、WTP(Web Tools Platform)