




已阅读5页,还剩21页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
深入理解查找(Search)功能及其扩展点查找功能是 Eclipse 中一个非常重要的特性,它提供了丰富的查找结果, 人性化的结果展示, 以及方便的定位,并可以查看查找历史记录(用户可以配置历史记录的个数)和使用上一次的条件重新运行查找功能。Eclipse3.4 插件开发版本提供了四种查找功能,包括文件查找,任务查找,Java 查找和插件查找,IBM RSA(Rational Software Architect)更是提供了多达八种的查找功能,因此,如何扩展 Eclipse 的查找功能,并实现特定于我们自己插件的查找功能,是插件开发者需要掌握的重要技能,本文将首先概要介绍 Eclipse 的查找功能;然后详细说明如何进行扩展查找功能,包括需要使用的扩展点和涉及到的接口和函数;最后以一个实例的形式引导读者深入理解 Eclipse 的查找功能。引言查找功能是计算机语言开发环境 / 平台的一个非常重要的特性。Eclipse 也不例外,它提供了丰富的查找功能(用户可以输入正则表达式或任意字符串,指定查找范围和匹配选项等等),并且提供了简单易用的接口方便开发人员扩展。Eclipse 的查找功能是基于 MVC 设计模式架构的,因此如果读者先前对 MVC 模式了解的话,有助于读者理解 Eclipse 的查找框架。在 Eclipse 的开发平台中,通过快捷键 CTRL+H 或者 Search 菜单可以激活其查找功能,如图 1 为 Eclipse3.4 插件开发版本按下快捷键时弹出的查找对话框(Search Dialog)。图 1. Eclipse3.4 版本的查找对话框如图 2 为 IBM RSA7.5.2 版本按下快捷键时弹出的查找对话框,提供了多大八种查找功能。图 2. IBM RSA7.5.2 版本的查找对话框总体而言,Eclipse 中的查找功能由三部分组成:查找对话框、查找页面和查找结果集视图;下面分别就这三部分进行具体描述。查找对话框是 Eclipse 查找功能的入口,Eclipse 中所有的查找功能都可以在该对话框中找到,如图 1 和图 2 显示了 Eclipse 和 IBM RSA 中的查找对话框。查找对话框中包含了当前 Eclipse 开发平台提供的所有查找页面,如果用户页面觉得页面太多,可以通过“Customize ”按钮定制,只显示使用频率较高的查找页面,隐藏其它页面。虽然我们不能对这些页面排序,然而,Eclipse 提供了相应的扩展点(Extension point)让开发人员定制其查找页面的位置(通过 tabPosition 属性可以指定,下一节会进行详细介绍)。查找页面是查找功能的入口,提供了查找模式和条件等内容的输入界面 GUI。在 Eclipse 中,为了保持查找功能的一致性,当我们的插件需要提供查找功能,通常会为其创建一个查找页面,并放在查找对话框里面。每一个查找功能对应有一个查找页面,用于接收用户进行查找的内容,范围等输入条件。如图 3 为 Clear Case 插件的查找页面。图 3. Eclipse 中 ClearCase 的查找页面作为一个完整的查找框架,还需要提供一个显示查找到结果集的界面。在 Eclipse 中,这个界面叫做查找结果集视图,它提供了丰富的工具栏和菜单,诸如上 / 下一个匹配项、重新查找、展开和收缩结果集等操作,并且可以根据查找结果的类型用相应的编辑器打开。Eclipse 中,所有的查找功能共用一个视图,该视图提供两种显示方式:表格(TableViewer)和树状结构(TreeViewer)。查找结果视图的标题为“Search”,如图 4 所示为作者使用 Eclipse 自带的文件查找搜索“*”的结果集视图。图 4. Eclipse 中显示查找结果的视图回页首Eclipse 查找功能的扩展点由上一节我们可知,Eclipse 的查找功能主要是由三部分组成:查找对话框、查找页面和查找结果集视图,至此,我们对 Eclipse 的查找功能有了感观的认识,本小节将从 Eclipse 提供的扩展点,函数,接口和类等方面详细说明 Eclipse 的查找功能。查找对话框 / 查找页面的扩展点如果我们想要插入一个查找页面到查找对话框中,那么需要添加扩展点 org.eclipse.search. searchPages。该扩展点允许其他插件为特定的查找功能注册属于自己的查找页面。下面说明需要注意的扩展点的一些属性: id 查找页面的唯一标志。 label 显示在查找对话框中页面的标题。 class 创建查找页面显示的 control 的类,该类通常继承抽象类 org.eclipse. jface.dialogs. DialogPage,并且实现接口 org.eclipse.search.ui. ISearchPage。 sizeHint 暗示该查找页面激活时的大小,其输入格式为width, height, 如50, 60。 tabPosition 整形数字,表示该查找页面在查找对话框中显示的位置,查找对话框中包含一个 TabFolder,TabFolder 包含了若干个页面,如果该元素没有指定,那么 Eclipse 将按照这些页面标题的字母顺序进行排列。数字越小,其对应的页面越靠前。 enabled 如果该属性没有指定或者为 false,那么当用户通过 CTRL+H,或者 search 菜单激活查找对话框时,该页面不会自动显示,用户可以通过“Customize” 按钮手动显示该页面。 canSearchEnclosingProjects 和 showScopeSection 如果这两个属性都设置为 true,那么 Eclipse 会自动添加一个 Scope 到你的查找页面的最下面,如图 5 所示为 File 查找的 Scope 域,不需要用户单独创建该区域。 图 5. 文件查找页面的 Scope 区域为了更好地说明如何使用该扩展点,举一个例子说明,如下为 org.eclipse.search 插件中的文件查找页面实现的扩展点代码,位于 plugin.xml 文件中。 查找结果视图(Search Result View)的扩展点对 org.eclipse.search.searchPages 扩展后,当我们按下查找(Search)按钮后,Eclipse 的查找框架会激活查找结果集视图,那么如何让我们自己设计的界面显示在查找结果集视图中呢?答案很明显,通过添加 org.eclipse.search.seacrhResultViewPages 扩展点,填充相应的扩展点属性,便可以激活我们自己设计的界面,并用该界面显示查找到的匹配结果集。下面讲解扩展点 seacrhResultViewPages 中比较重要的一些属性。 searchResultClass 用于表示查找结果集的类,需要实现接口 ISearchResult,由于实现该接口需要实现较多的方法,因此 Eclipse 提供了一个抽象类,用于表示文本查找的结果集,该抽象类(类名为 AbstractTextSearchResult)实现了 ISearchResult 的大部分接口,如果我们实现的查找功能是文本查找,那么就可以继承该类,同时实现少量的方法即可,该类需要和类 AbstractTextSearchViewPage 同时使用 class - 用于显示查找结果的页面类,需要实现接口 org.eclipse.search.ui. ISearchResultPage,由于实现该接口需要实现较多的方法,因此 Eclipse 提供一个抽象类(类名为 AbstractTextSearchViewPage)实现了该接口,该类主要用于显示文本查找的结果集。如果我们实现的查找功能是文本查找,那么只需继承该类并实现少量的方法即可。AbstractTextSearchViewPage 和 AbstractTextSearchResult 通常一起使用,当然还需要用到 Match 类和 MatchEvent 等类,下小节将会详细说明。 为了更好地说明如何使用该扩展点,举一个例子说明,如下为 org.eclipse.search 插件中的文件查找结果集视图实现的扩展点代码,位于 plugin.xml 文件中。 Eclipse 主菜单的查找(Search)菜单中加入你的菜单项对一些重要的查找功能,我们希望提供多种途径激活这些功能。如添加一个菜单项到查找(Search)主菜单中,如图 6 所示为文件查找的菜单项。图 6. Eclipse 自带文件查找的菜单那么如何添加我们自己的菜单项到 Eclipse 的查找主菜单中呢?答案是:添加 org.eclipse.ui. actionSets 扩展点,然后创建一个 action, 并且 action 的 menuBarPath 设置为 org.eclipse.search. menu/dialogGroup。为了更好地说明如何使用该扩展点,举一个例子说明,如下为创建一个”Am Search ”菜单项到 Search 主菜单中实现的扩展点代码,位于 plugin.xml 文件中。 相关的函数、接口和类对查找结果集排序通常我们以表格(TableViewer)和树状结构(TreeViewer)显示匹配的结果集,因此,自然涉及到对结果集排序的问题。在 Eclipse3.0 版本之前,如果需要对查找结果集视图中的 TableViewer 或 TreeViewer 进行排序,则需要使用扩展点 org.eclipse.search.searchResultSorters。但是,3.0 以后的版本不需要添加该扩展点,可以直接写代码对 TableViewer 或 TreeViewer 排序,只需继承 org.eclipse.jface.viewers.ViewerSorter。下面给出了一个简单的排序类代码。如果想让下面代码工作,则需要设置该类为 TableViewer 的 Sorter,通过调用函数 setSorter 方法实现。 public class ESearchResultSorter extends ViewerSorter private int columnIndex = -1 private int dir = SWT.DOWN; public BGSearchResultSorter(int columnIndex, int dir) super(); this. columnIndex = columnIndex; this.dir = dir; public int compare(Viewer viewer, Object e1, Object e2) int returnValue = 0; If(0 = columnIndex) returnValue = StringUtil.getCollator().compare(e1,e2); if (this.dir = SWT.DOWN) returnValue = returnValue * -1; return returnValue; Match 和 SearchResultEvent 类Eclipse 针对文本查找,除了提供前面讲到的 AbstractTextSearchViewPage 和 AbstractTextSearchResult 类外,还提供了配套的类 Match,MatchEvent 和 RemoveAllEvent(均继承类 SearchResultEvent),从而实现文本查找功能。如果我们也需要开发基于文本查找的功能,那么完全可以继承或使用这些类,否则,为了与 Eclipse 的查找框架保持一致和加强我们插件的可扩展性,建议大家也创建类似的类,并实现相应的功能。下面分别就这些类进行说明。1. org.eclipse.search.ui.text.Match 类该类用于表示查找过程中匹配的对象,是 Eclipse 为文本查找定义的 Match 类,该类包含匹配的元素(文件或资源等等),查找字符串在该元素中的起始偏移量(offset)和匹配长度,如果我们的查找功能是基于文本的,那么可以继承该类,否则,我们可以自己定义 Match 类(不用继承该类)。2. org.eclipse.search.ui.SearchResultEvent 类该类保存了提供给事件(Event)接收者需要的对象,例如,如果该事件为增加一个 Match 类对象,那么通过这个事件可以获取该对象。基于文本查找的两个时间 MatchEvent 和 RemoveAllEvent 均继承该类,其中 MatchEvent 类用于增加或删除 Match 对象,RemoveAllEvent 为删除所有 Match 对象。因此,我们在开发查找功能时需要继承该类 SearchResultEvent,提供我们的查找功能与该事件相关的对象,由 org.eclipse.search.ui.ISearchResult 激活该事件。一般而言,继承类会提供事件的类型(如增加,删除匹配项等),匹配的结果集(如包含 Match 的集合(Collection),可以参考 MatchEvent 和 RemoveAllEvent 类。3. org.eclipse.search.ui.ISearchResult 接口该接口用于表示查找结果集。前面讲到的 org.eclipse.search.searchPages 扩展点的属性 searchResultClass 对应的类需要实现该接口。Eclipse 提供的表示文本查找结果集的抽象类 org.eclipse.search.ui.text.AbstractTextSearchResult 实现了该接口。如果我们实现基于文本查找的功能,那么可以继承该类,实现少量的方法即可。一般而言,在实现该接口的继承类中会描述匹配结果集的结构,例如,包括了 Match 集合和 org.eclipse.search.ui.ISearchResultListener(下面将会讲到)集合等。4. org.eclipse.search.ui.ISearchResultListener 接口该接口表示查找结果集发生变化的事件接口。当结果集发生变化时,通知事件监听者(这里为查找结果集视图)作出相应的行为。该接口中提供了一个方法 searchResultChanged,其参数为 SearchResultEvent。就实现而言,我们可以让查找结果集视图实现该接口,并调用模型(Model,我们这里表现为 ISearchResult)中的方法注册 / 注销该事件(继承方式),另外,我们也可以在查找结果集视图的构造函数中定义匿名类,实现该接口中的方法,同时调用模型中的方法注册 / 注销该匿名类事件(组合方式)。从大部分的实现方法来看,我们会使用后者(组合方式),因为该接口中只有一个方法,并且使用匿名类也更加灵活。Eclipse 针对文本查找的结果集视图抽象类 org.eclipse.search.ui.text.AbstractTextSearchViewPage 也是采用匿名类的方式。5. org.eclipse.search.ui.NewSearchUI 类该类提供了访问 Eclipse 查找 GUI 的入口方法,它采用 Facade 设计模式。下面就该类中的一些重要函数进行说明。调用下面这个方法表示在当前的 Page 里激活查找结果集视图(search result view)。 activateSearchResultView() 调用下面这个方法表示发送 cancel 命令到后台运行的 query。 cancelQuery(ISearchQuery query) 调用下面这个方法表示获取当前的查找结果集视图。 getSearchResultView() 调用下面这个方法表示打开查找对话框,并激活由 pageId 指定的查找页。 openSearchDialog(IWorkbenchWindow window, String pageId) 调用下面这些方法表示运行指定的 query,可以在前台或者后台运行,此时 Eclipse 会启动一个 job 运行。 runQueryInBackground(ISearchQuery query) runQueryInBackground(ISearchQuery query, ISearchResultViewPart view) runQueryInForeground(IRunnableContext context, ISearchQuery query) runQueryInForeground(IRunnableContext context, ISearchQuery query, ISearchResultViewPart view) 回页首编程实践通过前两节的讲述,相信大家对 Eclipse 的查找框架已经很清楚了,下面将给出一个例子说明如何使用这些扩展点,如何实现接口和继承类,如何让我们的查找功能在 Eclipse 的查找框架下工作。首先,如图 7 给出了 Eclipse 查找框架的流程,本文将按照这个流程图中的步骤及其各个步骤涉及到的方法,接口和类,给出它们的代码框架,读者想要让其运行,必须实现相应的方法,接口和类。图 7. Eclipse 查找框架的流程开始阶段(弹出查找对话框)当用户按下 Ctrl + H 键,或者通过 Eclipse 的 Search 菜单选择相应的查找项(如果我们定义了自己的 Action 在 Search 菜单中),Eclipse 将会弹出查找对话框。如果只需要 Crtl+H 激活查找对话框,那么添加 searchPages 扩展点,并填写相应的属性,而不需要其他额外的代码,在查找对话框中就会有我们的查找页(还记得前面讲的 searchPages 扩展点的 enable 属性吗,如果该属性设为 true,那么扩展的查找页将会出现在对话框中,否则将被隐藏,需要通过“Customize ”按钮激活)。如果需要在 search 菜单中定义自己的菜单,那么首先添加 actionSets 扩展点,如下所示。 然后再事件处理中通过 NewSearchUI 提供的 openSearchDialog 函数打开对话框,此时需要提供查找页的 ID,这里我们定义为 ESearchPage,后面将会讲到。 public class ESearchHandler implements IWorkbenchWindowActionDelegate private IWorkbenchWindow fWindow; public void init(IWorkbenchWindow window) fWindow = window; public void run(IAction action) if (fWindow = null | fWindow.getActivePage() = null) Activator.beep(); return; NewSearchUI.openSearchDialog(fWindow, ESearchPage.ID); 用户输入(查找页面)所有查找功能的输入都是在查找页面进行的,因此,我们需要使用 searchPages 扩展点,提供自己的查找页面,从而在该页面内定制我们的 GUI(如何摆放 Widget,如何布局等等)。以下是扩展点的实现。 下面分析 ESearchPage 的代码,该类继承 DialogPage,并且实现 ISearchPage 接口。该类中,我们需要重载 createControl 方法,用于创建 Widgets,布局我们的查找页面。通常,我们需要把当前用户的输入和选择保存到 DialogSetting 中,如果查找页面需要输入文本,那么我们可以定制历史输入的个数,该值通常为 20(Eclipse 文件查找)。需要注意:在 createControl 方法中,我们必须调用方法 setControl 来设置查找页面的上层控件,否则的话,查找页面会创建失败(后面会给出失败的原因)。下面给出了该类的一些关键代码为参考之用。 public class ESearchPage extends DialogPage implements ISearchPage private ISearchPageContainer fContainer; / 定义页面需要的 control public ESearchPage() Override public void createControl(Composite parent) / 创建显示在查找页面的 control setControl(parent); public boolean performAction() NewSearchUI.activateSearchResultView(); NewSearchUI.runQueryInBackground(getSearchQuery(); return true; public ISearchQuery getSearchQuery() return new ESearchQuery(this.fPattern.getText().trim(); protected ISearchPageContainer getContainer() return this.fContainer; public void setContainer(ISearchPageContainer container) this.fContainer = container; 前面讲到,如果不在 createControl 方法中调用 Setting 方法,那么查找页面的 widgets 将会创建失败,为什么呢?如果你单步跟踪调试,会发现类 ernal.ui.SearchDialog 中包含调用我们创建的查找页面代码,如下所示,从代码中可以看出,如果没有调用 setControl 方法,那么 page.getControl() 将返回 Null 值,故创建失败,Eclipse 将提示“The creation of the page failed.”错误信息。 private Control createPageControl(Composite parent, final SearchPageDescriptor descriptor) ISearchPage page= descriptor.getPage(); if (page = null | page.getControl() = null) Composite container= new Composite(parent, SWT.NONE); Label label= new Label(container, SWT.WRAP); label.setText(Messages.format(SearchMessages. SearchDialog_error_pageCreationFailed, descriptor.getLabel(); container.setLayout(new GridLayout(); label.setLayoutData(new GridData(); return container; 查找入口(启动 Job)当我们点击查找对话框中“Search”按钮,这时候会调用 ESearchPage 类中的 performAction() 方法。该方法将启动 Job 执行 Query(实现了 ISearchQuery 的类),我们可以选择在前台还是后台运行(具体方法,可以参考上一节中 NewSearchUI 提供的静态方法)。一般而言,performAction 方法首先调用函数 activateSearchResultView() 激活查找结果视图,然后调用函数 runQueryInBackground() 运行指定的 Query。上面讲到,在运行 Query 之前,通常会调用方法 NewSearchUI.activateSearchResultView() 激活查找结果视图(需要使用 searchResultPages 扩展点),此时仅仅是当前查找功能的结果集界面显示。查找结果视图继承 Page 类,并实现 ISearchResultPage 接口,下面分析该类中的一些关键代码。通常我们会在构造函数中定义 ISearchResultListener,并提供相应的监听方法。在 setInput 方法中,需要根据当前显示在查找结果视图中的匹配结果集合和新的匹配结果集合状态和值,注册或注销该事件。所有的匹配结果集合均通过调用查找结果集视图中 TableViewer 的内容提供者(Content Provider)逐个插入到 TableViewer 中。getLabel() 用于显示在 TableViewer/TreeViewer 上面的一个 label 的内容,通常用于显示查找到多少个匹配项。下面给出了部分关键代码,读者可以参考 AbstractTextSearchViewPage 类中的一些实现。 public class ESearchResultPage extends Page implements ISearchResultPage private TableViewer fTableViewer; protected ESearchResult fInput; protected ISearchResultViewPart fViewPart; protected ISearchResultListener fListener; protected String fId; public ESearchResultPage() this.fListener = new ISearchResultListener() public void searchResultChanged(SearchResultEvent e) ESearchResultPage.this.handleSearchResultChanged(e); ; public void createControl(Composite parent) public String getLabel() ESearchResult result = getInput(); if (result = null) return ; return result.getLabel(); public void setInput(ISearchResult search, Object uiState) ISearchResult oldSearch = (ISearchResult) this.fTableViewer.getInput(); this.fTableViewer.setInput(null); if (oldSearch != null) oldSearch.removeListener(this.fListener); this.fInput = (ESearchResult) search); if ( fInput != null & fInput.getElements().size() 0) search.addListener(this.fListener); this.fTableViewer.setInput(search); if (uiState instanceof ISelection) this.fTableViewer.setSelection(ISelection) uiState, true); 查找(执行 Query)当调用 runQueryInBackground 或 runQueryInForeground 方法之后,Eclipse 查找框架会启动一个 Job 运行我们定义的 Query,该类是 Eclipse 查找框架中最主要的一个类之一,它定义了如何进行查找,同时把查找匹配项添加到 ISearchResult,并且以友好的用户体验方式即 progressMonitor 显示目前查找的进度。该类提供了很多方法,例如,是否可以重新运行,是否可以在后台运行及显示进度的对话框的标题等等,下面给出类 ESearchQuery 的部分关键代码的实现。 public class ESearchQuery implements ISearchQuery ESearchResult fSearchResult; String fPattern; public ESearchQuery(String pattern) this.fPattern = pattern; this.fSearchResult = ESearchResult.createInstance(this); public boolean canRerun() return true; public boolean canRunInBackground() return true; public String getLabel() return Example Search; public ISearchResult getSearchResult() return fSearchResult; public IStatus run(IProgressMonitor monitor) throws OperationCanceledException try / 表明查找开始 monitor.beginTask(taskname, totalCount); / 在指定的范围逐个查找结果集,如果找到,添加到 ISearchResult / 其流程大致如下 For( ) 找到匹配项 构造一个 Match 调用 ISearchResult 的函数添加该 Match Monitor.work(1) catch (RuntimeException e) finally if (monitor != null) monitor.done(); 从上面的描述可知,在类 ESearchQuery 会调用 ESearchResult 类中的方法添加查找的匹配项,接下来将讲解查找结果类 ESearchResult。EsearchResult 类实现 ISearchResult 接口,用于保存查找到的匹配项。该类除了要实现最重要的两个方法,添加和删除 ISearchResultListener 方法外,同时需要定义添加匹配的结果集,删除结果集等方法。下面给出该类中的一些关键代码,其中添加匹配的结果集的方法 addMatch,添加传入的匹配项到匹配结果集合中,同时通知 ISearchResultListener 事件的监听者。 public class ESearchResult implements ISearchResult protected List elements; public void addMatch(Match match) boolean hasAdded= false; synchronized (elements) hasAdded= doAddMatch(match); if (hasAdded) fireSearchResultEvent(ESearchResultEvent.ADDED, match) protected void fireSearchResultEvent(ESearchEventType eventType, EMatch match) ESearchResultEvent event = new ESearchResultEvent(this, eventType); event.setMatche(match); for (Iterator e = this.searchResultsListeners .iterator(); e.hasNext();) ISearchResultListener listener = (ISearchResultListener) e.next(); listener.searchResultChanged(e
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 付费频道合同5篇
- 农业项目入股合同范本
- 高一下学期语文期末考试试卷及答案
- 研究老年医学及长寿基因分析
- 品牌营销在化妆品行业的应用
- 生物医学工艺流程研究
- 采矿技术员考试试题及答案
- 广电网络考试试题及答案
- 2025年计算机原理试卷及答案
- 2025年山东中小学教师招聘考试模拟试题及答案
- 二年级数学下册口算天天练
- 有机化学课件(李景宁主编)第1章-绪论
- 全友导购员培训资料(机密)
- 白话译文《渔樵问对》(全篇)
- 医院消毒灭菌效果监测制度
- +GF+-SIGNET8850电导率变送器手册
- 大豆收购合同范本
- 2023学年完整公开课版水准仪认识
- 人文地理学(王恩涌)
- 教育学第五章教师与学生
- GB/T 5267.1-2002紧固件电镀层
评论
0/150
提交评论