定义自己的Common Navigator
来源:互联网 发布:西安seo外包公司 编辑:程序博客网 时间:2024/06/05 17:28
http://liugang594.iteye.com/blog/153413
所谓的Navigator,可以简单的理解为Eclipse中的资源导航视图,例如:
Project Explorer视图
Project Explorer视图
这一系列,我们就要来实现一个类似的Navigator视图。
一、 定义Navigator
在开始之前,我们先了解一下做Navigator需要的扩展点:
1. org.eclipse.ui.navigator.viewer
这个扩展点就是用来定义整个Navigator用的。例如:Navigator绑定到哪个View上;它的Content是什么;它的actions是什么;它怎么支持拖动的,等等。
这个扩展点的实质是将一些内容组合到一起来决定这个Navigator的,所以它本身几乎是不需要写代码的。
2. org.eclipse.ui.navigator.navigatorContent
上一个扩展点,我们讲它需要有content的提供、action的提供者等等。这个扩展点就是用来提供这个用的。
当然,除了上面两个扩展点,我们也说是我们的Navigator需要绑定到一个view上,所以也需要一个org.eclipse.ui.views扩展点,因为这个扩展点比较通用,这里就不具体说了。
Navigator部分的API帮助,可以到以下包去找:org.eclipse.ui.navigator。所以显然你需要把这个插件包添加到依赖项里。
我们在做的时候也可以参照已有的实现:
图一
图一中,红色部分就是对应需要用到的两个扩展点,蓝色部分就是对应的定义了这个扩展点的插件。我们可以参考它们相应的实现来了解更多的应用方面的知识。
好。下面我们就来开始我们自己的Navigator。首先我们需要有一个插件工程。这个就不说了。首先我们定义一个org.eclipse.ui.views的扩展声明,如下:
<extension point="org.eclipse.ui.views"> <category id="com.tibco.cdc.liugang.navigator.category" name="Common Navigator"> </category> <view allowMultiple="false" category="com.tibco.cdc.liugang.navigator.category" class="org.eclipse.ui.navigator.CommonNavigator" icon="icons/alt_window_16.gif" id="com.tibco.cdc.liugang.navigator.view" name="Sample Navigator"> </view> </extension>
这里需要注意的是:
class需要设定为“org.eclipse.ui.navigator.CommonNavigator”,当然你也可以定义自己的实现。一般来说都没有必要。
现在我们已经可以运行,看到一个view了:
图二
Ok,一个view就定义完了,下面就是我们要关注的两个扩展点的实现了。这一节,我们先讲第一个扩展点org.eclipse.ui.navigator.viewer,后两节会讲到另一个扩展点:org.eclipse.ui.navigator.navigatorContent
所以我们再定义一个org.eclipse.ui.navigator.viewer扩展声明。在继续之前我们先看一下下图:
图三
其中:viewerActionBinding对应于action的支持,例如选择某个对象,显示一个什么的右键菜单;viewerContentBinding对应于内容提供,就是在这navigator上显示什么内容;viewer对应的就是这个navigator要显示在哪个view上。
这一节里,我们将利用已经有的定义来充实这个扩展点。具体哪些内容可以填充,请到图一的各个实现里去找就可以了。这里我参照resources的实现(后面我们会讲到自定义实现),如下:
<extension point="org.eclipse.ui.navigator.viewer"> <viewer viewerId="com.tibco.cdc.liugang.navigator.view"> </viewer> <viewerActionBinding viewerId="com.tibco.cdc.liugang.navigator.view"> <includes> <actionExtension pattern="org.eclipse.ui.navigator.resources.*"> </actionExtension> </includes> </viewerActionBinding> <viewerContentBinding viewerId="com.tibco.cdc.liugang.navigator.view"> <includes> <contentExtension pattern="org.eclipse.ui.navigator.resourceContent"> </contentExtension> </includes> </viewerContentBinding> </extension>
好,我们现在运行看看:
图四
OK,我们的view里已经有内容了,而且已经支持了右键菜单了。现在还不支持过滤,如果要支持一个过滤器也是容易的。我们只要加一个content声明就可以了。例如加上:
<contentExtension pattern="org.eclipse.ui.navigator.resources.*"> </contentExtension>
加上上面声明,我们就支持所有resource的实现。显示如下:
图五
看图五中,以“.”开始的资源已经被过滤了。并且我们也支持了一些其他的过滤和内容显示设置。
OK,我们已经初步有了一个自己的Navigator了。下面我们会逐渐的增加更多的内定。
这一节和下一节我们都将来关注另一个扩展点:
org.eclipse.ui.navigator.navigatorContent
首先我们先增加一个扩展声明,然后看看它支持什么东西:
图六
可以看到在这个扩展点下可以定义四个子元素。其中:
actionProvider:用来定义可以action的。
commonFilter:定义过滤器
commonWizard:定义快捷wizard
navigatorContent:定义内容导航
其中第一和第三个元素通常不需要扩展。而且我发现这两个扩展点几乎没有实现,很奇怪。我们一会可以看到,在navigatorContent元素也有两个同样的扩展,一般都是在这个元素里做扩展。
说了和没说一样,下面就以例子来讲解。
- commonFilter
先讲简单的commonFilter,很显然是用来定义过滤的。在第一节里,我们已经给我们的navigator加了resource的过滤。我们再来加一些。例如,我们想有一个过滤掉全部以pda结尾的文件。那我们可以这样实现:
<commonFilter activeByDefault="false" description="this used to filter all files whose extensions is pda" id="com.tibco.cdc.liugang.navigator.filter.pda" name="Filter pda files"> <filterExpression> <and> <instanceof value="org.eclipse.core.resources.IFile"> </instanceof> <test property="org.eclipse.core.resources.extension" value="pda"> </test> </and> </filterExpression></commonFilter>
这样我们就定义好了一个过滤器。不过我们要使用它的话,需要把它加到我们的navigator上,所以在我们第一节定义的viewer扩展点的contentBinding的includes里加上一句:
<contentExtension pattern="com.tibco.cdc.liugang.navigator.filter.pda"> </contentExtension>
OK,我们已经完成了我们的过滤声明:
图七
图七中,当我们选中我们扩展的过滤器后,所有的pda文件都已经消失了。
- navigatorContent
下面来完成一个navigator content扩展。这个稍微有点复杂。首先我们先完成一个声明。如下
<navigatorContent activeByDefault="true" contentProvider="com.tibco.cdc.liugang.navigator.content.XMLTreeContentProvider" icon="icons/alt_window_16.gif" id="com.tibco.cdc.liugang.navigator.navigatorContent" labelProvider="com.tibco.cdc.liugang.navigator.content.XMLLabelProvider" name="XML Navigator Content" priority="normal"></navigatorContent>
这里我想做的是:如果是一个xml文件,则显示它的结构。这主要是要完成contentProvider和labelProvider。我们先完成这个。代码就不贴了。可以参考附件!
需要注意的是:这里我们是要给xml文件加一个内容导航,因此在contentProvider里传入的有可能是IFile类型。所以我们要注意我们的contentProvider的实现方法。
定义完了一个内容以后,并不是会自动被显示的,我们需要给它加一个触发点。这就是要在navigatorContent下增加一个子元素“triggerPoints”,triggerPoints用来指示我们的扩展所感兴趣的内容。实际我们的触发点就是一个xml文件,因此我们可以如下实现:
<triggerPoints> <and> <instanceof value="org.eclipse.core.resources.IFile"> </instanceof> <test forcePluginActivation="true" property="org.eclipse.core.resources.extension" value="xml"> </test> </and></triggerPoints>
其实意思就是:如果选择的是一个文件,并且文件扩展名为“xml”,则触发我们的内容导航。好了,这样就完成了我们的xml文件的内容导航,最后不要忘了把它加到我们的Navigator的viewer声明里去,如下在viewerContentBinding的includes下加上:
<contentExtension pattern="com.tibco.cdc.liugang.navigator.navigatorContent"> </contentExtension>
现在我们的图如下:
图八
补充:
一个完整的内容导航,我们除了要显示它之外,还需要有一个监听机制,就是eclipse已经实现的resourceChangeListener。这样当外部有修改时,我们的内容也能显示正确。
OK,我们已经有了一个初步可运行的Navigator了,现在它看起来已经比较丰富了。不过我们在xml文件下的任意结点上点右键时,都没有菜单显示。另外假如我们有一个新的wizard,我们也想像java的package explorer视图一样显示在new菜单的那一层。那我们应该怎么做呢?这一节就来介绍这部分的实现。
实际上,从上面的介绍里,很多人可能都已经知道了怎么完成这些事情。不过这里还是写一个完整的介绍过程。
先说一下我们的目标:在IResource对象的new菜单里,加上java project wizard。在xml文件的node上,加一个菜单用来显示它的所有属性。
首先我们完成第一件事。
增加快捷Wizard
第二节中,我们提到过,在org.eclipse.ui.navigator.navigatorContent扩展点的navigatorContent里也有两个子扩展:commonWizard和actionProvider。
这里要加一个wizard的快捷方式,就是需要扩展这个commonWizard。所以在上面我们扩展的navigatorContent里,我们再声明子扩展:commonWizard。如下:
<commonWizard type="new" wizardId="org.eclipse.jdt.ui.wizards.JavaProjectWizard"> <enablement> <instanceof value="org.eclipse.core.resources.IResource"> </instanceof> </enablement> </commonWizard>
有三种类型的wizard,这里我们选择new;然后就是指定wizardId,这里我们指定为java project wizard的ID;最后就是定义出现在条件,这里定义的条件就是如果选择的对象为IResource对象,则出现。
最后我们的图如下:
图九
显然你可以很简易的推到其他两种类型wizard的快捷定义。
增加自定义菜单
现在看我们的XML下的那些结点,点右键时没有菜单显示。这里我们就给他们加一个显示值的菜单。
要实现自定义菜单,我们就需要扩展和上面的commonWizard在同一级的actionProvider。先看一下我们的声明:
<actionProvider class="com.tibco.cdc.liugang.navigator.actions.LiugangCommonActionProvider" id="com.tibco.cdc.liugang.navigator.navigatorContent.actions"> <enablement> <instanceof value="org.w3c.dom.Node"> </instanceof> </enablement> </actionProvider>
这里有五个属性定义,不过我们需要关心的只有上面两个:class用来定义实现类;id唯一标识这个actionProvider。然后我们加了一个可用的约束条件:选择的对象需要是一个Node实例。
定义完actionProvider之后,我们就要注册这个actionProvider了。在我们的viewer扩展的viewerActionBinding的includes下面加一句就行了:
<actionExtension pattern="com.tibco.cdc.liugang.navigator.navigatorContent.actions"></actionExtension>
好,接下来我们先完成实现类,如下:
public class LiugangCommonActionProviderextends CommonActionProvider { private ActionpropertyAction; private ICommonViewerSiteviewSite; public LiugangCommonActionProvider() { } @Override public void init(ICommonActionExtensionSite site) { super.init(site); viewSite = site.getViewSite(); propertyAction =new Action("Show Property") { @Override publicvoid run() { IStructuredSelection selection = (IStructuredSelection) viewSite .getSelectionProvider().getSelection(); Object firstElement = selection.getFirstElement(); if (firstElement instanceof Node) { Node selectedNode = (Node) firstElement; MessageDialog.openInformation(viewSite.getShell(), "Property", getAllAttributes(selectedNode)); } } }; } @Override public void fillContextMenu(IMenuManager menu) { menu.add(propertyAction); } private String getAllAttributes(Node node) { NamedNodeMap attributes = node.getAttributes(); String content ="<"; for (int i = 0; i < attributes.getLength(); i++) { Node item = attributes.item(i); content += item.getNodeName() +"=" + item.getNodeValue() + " "; } content +=">"; return content; }}
看起来像是我们已经完成了所有的过程。不过如果此时我们在node上点右键的话,并不出现右键菜单。为什么呢?
这里我们需要提到另一个扩展元素:possibleChildren。它和triggerPoints在同一层。
这个扩展元素指出我们的内容扩展中的哪些结点类型可以指供label和parent。如果你要实现editor link或者是想使得setSelection()方法可用,则必须提供这个扩展元素的声明。
这里,对应于我们点右键菜单,显然我们应该使得setSelection()方法可用,这样才能知道我们在资源树上选择了哪个node结点,最后传到我们的actionProvider的实现。完成我们的右键菜单。这里我们可以如下声明:
<possibleChildren> <or> <instanceof value="org.w3c.dom.Node"> </instanceof> </or> </possibleChildren>
最后效果如下:
图十
package com.tibco.cdc.liugang.navigator.content;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.List;import javax.xml.parsers.DocumentBuilder;import javax.xml.parsers.DocumentBuilderFactory;import javax.xml.parsers.ParserConfigurationException;import org.eclipse.core.resources.IFile;import org.eclipse.jface.viewers.ITreeContentProvider;import org.eclipse.jface.viewers.Viewer;import org.w3c.dom.Document;import org.w3c.dom.Element;import org.w3c.dom.Node;import org.w3c.dom.NodeList;import org.xml.sax.SAXException;public class XMLTreeContentProvider implements ITreeContentProvider {public Object[] getChildren(Object parentElement) {if(parentElement instanceof IFile){return getElements(parentElement);}else if(parentElement instanceof Node){NodeList childNodes = ((Node)parentElement).getChildNodes();List<Node> children = new ArrayList<Node>();for(int i=0;i<childNodes.getLength();i++){Node item = childNodes.item(i);if(item.getNodeType()!=Node.TEXT_NODE){children.add(item);}}return children.toArray();}return null;}public Object getParent(Object element) {if(element instanceof Node){return ((Node)element).getParentNode();}return null;}public boolean hasChildren(Object element) {//if(element instanceof Node){//return ((Node)element).getChildNodes().getLength()==0?false:true;//}return true;}public Object[] getElements(Object inputElement) {if (inputElement instanceof IFile) {try {InputStream is = ((IFile) inputElement).getContents();Element element = parseXML(is);is.close();return new Object[] { element };} catch (Exception e) {return null;}}return null;}private Element parseXML(InputStream is)throws ParserConfigurationException, SAXException, IOException {DocumentBuilder db = DocumentBuilderFactory.newInstance().newDocumentBuilder();Document document = db.parse(is);Element documentElement = document.getDocumentElement();return documentElement;}public void dispose() {}public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}}
- 定义自己的Common Navigator
- 定义自己的Common Navigator一
- 定义自己的Common Navigator二
- 定义自己的Common Navigator三
- Common Navigator Framework (CNF)
- Common Navigator Framework初探
- Common Navigator CNF
- eclipse自带的功能树 Common Navigator Framework
- 自己定义的格式
- 定义自己的Adapter
- 定义自己的异常
- 定义自己的快捷键
- 定义自己的View
- 定义自己的xml
- 定义自己的dialog
- 定义自己的dialog
- 定义自己的g_signal
- 定义自己的错误代码
- 一些牛人的blog
- Common Navigator Framework初探
- iptables防火墙
- 添加附件
- 杂记
- 定义自己的Common Navigator
- 杭电 ACM 1.2.3
- Java Socket线程的设计原理介绍
- 【2012.12.4】软件使用技巧
- static 的作用
- 串口开发 comm.jar
- 2012-12-1多校联考题 英语
- ScrumWorks 安装过程
- restrict 关键字