- 浏览: 127584 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
wind35:
32赞~~~
KDB+ database -
sunnyxiaoxi:
图片看不到
KDB+ database 初步 -
RonQi:
确实很有用的插件
eclipse插件 快速打开文件位置,在命令行打开文件位置 -
zhanshi258:
我们程序员讲究的是严谨,大部分人是讲娱乐
小唠叨 -
li498833284:
因为很多都是屏蔽字
小唠叨
转自 http://www.ibm.com/developerworks/cn/opensource/os-cn-ecl-search/index.html
查找功能是 Eclipse 中一个非常重要的特性,它提供了丰富的查找结果, 人性化的结果展示, 以及方便的定位,并可以查看查找历史记录(用户可以配置历史记录的个数)和使用上一次的条件重新运行查找功能。Eclipse3.4 插件开发版本提供了四种查找功能,包括文件查找,任务查找,Java 查找和插件查找,IBM RSA(Rational Software Architect)更是提供了多达八种的查找功能,因此,如何扩展 Eclipse 的查找功能,并实现特定于我们自己插件的查找功能,是插件开发者需要掌握的重要技能,本文将首先概要介绍 Eclipse 的查找功能;然后详细说明如何进行扩展查找功能,包括需要使用的扩展点和涉及到的接口和函数;最后以一个实例的形式引导读者深入理解 Eclipse 的查找功能。
<!--START RESERVED FOR FUTURE USE INCLUDE FILES--><!-- include java script once we verify teams wants to use this and it will work on dbcs and cyrillic characters --><!--END RESERVED FOR FUTURE USE INCLUDE FILES-->
如图 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 自带的文件查找搜索“*”的结果集视图。
由上一节我们可知,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 域,不需要用户单独创建该区域。
为了更好地说明如何使用该扩展点,举一个例子说明,如下为 org.eclipse.search 插件中的文件查找页面实现的扩展点代码,位于 plugin.xml 文件中。
<extension point="org.eclipse.search.searchPages"> <page id="org.eclipse.search.internal.ui.text.TextSearchPage" label="%fileSearch" icon="$nl$/icons/full/elcl16/tsearch_obj.gif" sizeHint="250,160" tabPosition="1" extensions="*:1" showScopeSection="true" canSearchEnclosingProjects="true" class="org.eclipse.search.internal.ui.text.TextSearchPage"> </page> </extension> |
对一些重要的查找功能,我们希望提供多种途径激活这些功能。如添加一个菜单项到查找(Search)主菜单中,如图 6 所示为文件查找的菜单项。
那么如何添加我们自己的菜单项到 Eclipse 的查找主菜单中呢?答案是:添加 org.eclipse.ui. actionSets 扩展点,然后创建一个 action, 并且 action 的 menuBarPath 设置为 org.eclipse.search. menu/dialogGroup。
为了更好地说明如何使用该扩展点,举一个例子说明,如下为创建一个”Am Search …”菜单项到 Search 主菜单中实现的扩展点代码,位于 plugin.xml 文件中。
<extension point="org.eclipse.ui.actionSets"> <actionSet id="org.eclipse.am.ui.workbenchActionSet" label="%actionSet.am.label" visible="true"> <action class="org.eclipse.am.ui.handlers.ESearchHandler" definitionId=" org.eclipse.am.ui.commands.ESearch" icon="icons/Search.gif" id=" org.eclipse.am.ui.commands.BGSearch" label="AM Search …" menubarPath="org.eclipse.search.menu/dialogGroup" style="push"> </action> </actionSet> </extension> |
对查找结果集排序
通常我们以表格(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 查找框架的流程,本文将按照这个流程图中的步骤及其各个步骤涉及到的方法,接口和类,给出它们的代码框架,读者想要让其运行,必须实现相应的方法,接口和类。
开始阶段(弹出查找对话框)
当用户按下 Ctrl + H 键,或者通过 Eclipse 的 Search 菜单选择相应的查找项(如果我们定义了自己的 Action 在 Search 菜单中),Eclipse 将会弹出查找对话框。
如果只需要 Crtl+H 激活查找对话框,那么添加 searchPages 扩展点,并填写相应的属性,而不需要其他额外的代码,在查找对话框中就会有我们的查找页(还记得前面讲的 searchPages 扩展点的 enable 属性吗,如果该属性设为 true,那么扩展的查找页将会出现在对话框中,否则将被隐藏,需要通过“Customize …”按钮激活)。
如果需要在 search 菜单中定义自己的菜单,那么首先添加 actionSets 扩展点,如下所示。
<extension point="org.eclipse.ui.actionSets"> <actionSet id="com.ibm.bg.ui.workbenchActionSet" label="Example" visible="true"> <action class="com.ibm.bg.ui.handlers.ESearchHandler" definitionId="com.ibm.bg.ui.commands.ESearch" icon="icons/lookup_criteria.gif" id="com.ibm.bg.ui.commands.ESearch" label="E Search" menubarPath="org.eclipse.search.menu/dialogGroup" style="push"> </action> </actionSet> </extension> |
然后再事件处理中通过 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,如何布局等等)。以下是扩展点的实现。
<extension point="org.eclipse.search.searchPages"> <page class="org.eclipse.book.example.pages.ESearchPage" enabled="true" id="org.eclipse.book.example.pages.ESearchPage" label="Search Example"> </page> </extension> |
下面分析 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 将会创建失败,为什么呢?如果你单步跟踪调试,会发现类 org.eclipse.search.internal.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<EMatch> 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<ISearchResultListener> e = this.searchResultsListeners .iterator(); e.hasNext();) { ISearchResultListener listener = (ISearchResultListener) e.next(); listener.searchResultChanged(event); } } |
上面讲到 ESearchResult 类包含了匹配项的集合,一般我们会定义一个用于保存匹配对象的类,如 Eclipse 中为文本查找的匹配项提供了 Match 类,该类定义了匹配项的偏移量,长度,匹配的对象等等,如果我们的匹配项具有这些特征,那么可以继承该类,否则新建一个 Match 类即可。下面是一个简单的匹配类的实现 EMatch 类。
public class EMatch { EDataObject fMatchElement; public String getName(){ return fMatchElement.getName(); } public EMatch(EDataObject matchElement) { fMatchElement = matchElement; } } |
同时,在查找到匹配项,需要通知事件的监听者当前事件的类型(通常有三种:增加了匹配项,删除匹配项和清空匹配项),Eclipse 查找框架提供了 SearchResultEvent 基类,文本查找定义了两个类:MatchEvent(包含增加和删除匹配项类型事件),RemoveAllEvent(清空匹配项事件)。通常在我们开始查找之前,发送清空匹配项类型事件,让查找结果集视图清空上一次的匹配项,然后再查找的过程,如果查找到匹配项,则发送增加匹配项事件,使查找结果集视图把该匹配项添加到界面上(TableViewer 或 TreeViewer)。这里不给出查找结果集事件的关键代码,因为 MatchEvent 和 RemoveAllEvent 的源码已经很清晰,读者可以参考这两个类的实现。
显示查找结果集
前面在讲激活查找结果集视图的时候,已经说明在 Eclipse 的查找框架内,并不是通过 TableViewer 的 setInput 方法把匹配的结果集显示在 Search 视图中,而是通过 TableViewer 的 add 方法把匹配项添加到查找结果集视图中。具体而言,Eclipse 查找框架会启动一个 UIJob 定时地把查找到的匹配项添加到 Search 视图中,这样可以增强用户体验。以 AbstractTextSearchViewPage 中的 UpdateUIJob 为例,其间隔时间为 500 毫秒。通过调用 runBatchedUpdates 方法把当前查找到的匹配项添加到 Search 视图中,以下是其中的一些关键代码。
private class UpdateUIJob extends UIJob { public UpdateUIJob() { super("updating"); //$NON-NLS-1$ setSystem(true); } public IStatus runInUIThread(IProgressMonitor monitor) { Control control= getControl(); if (control == null || control.isDisposed()) { // disposed the control while the UI was posted. return Status.OK_STATUS; } runBatchedClear(); runBatchedUpdates(); if (hasMoreUpdates() || isQueryRunning()) { schedule(500); } else { fIsUIUpdateScheduled= false; updateBusyLabel(); if (fScheduleEnsureSelection) { fScheduleEnsureSelection= false; AbstractSearchResult result = getInput(); if (result != null && fViewer.getSelection().isEmpty()) { navigateNext(true); } } } fViewPart.updateLabel(); return Status.OK_STATUS; } } |
下面我们分析一下 runBatchedUpdates 中的代码,该函数会调用 elementsChanged 函数触发 TableViewer 调用 add 方法,把相应的匹配项添加到 TableViewer 中,然后清除从需要更新的匹配项集合中删除,如下为其关键代码。
private synchronized void runBatchedUpdates() { elementsChanged(fBatchedUpdates.toArray()); fBatchedUpdates.clear(); updateBusyLabel(); } |
前面讲到,runBatchedUpdates 方法会将当前查找到的匹配项添加到 Search 视图中,那么如何获取当前查找到的匹配项呢?这就需要借助 ISearchResultListener,即当前查找到的匹配项通过我们定义的事件监听函数获取,如下为定义查找结果集发生变化的类及其监听函数 handleSearchResultChanged 中的关键代码。我们注意到,MatchEvent 中包含事件的类型和当前查找到的匹配项,如果当前事件为 REMOVED_ALL 类型,那么从查找结果视图中清除所有的匹配项。
fListener = new ISearchResultListener() { public void searchResultChanged(SearchResultEvent e) { handleSearchResultChanged(e); } }; protected void handleSearchResultChanged(final SearchResultEvent e) { if (e instanceof MatchEvent){ MatchEvent event = (MatchEvent) e; if(event.getKind() == MatchEvent.REMOVED_ALL){ postClear(); } else{ postUpdate(((MatchEvent) e).getMatches()); } } } |
由于增加 / 删除匹配项设计 GUI 操作,因此我们需要启动 UIJob 运行,因此,runBatchedUpdates 函数调用 postUpdate 函数启动 Job,把匹配项显示到查找结果视图上。如下为 postUpdate 的一些关键代码。
private synchronized void postUpdate(Match[] matches) { evaluateChangedElements(matches, fBatchedUpdates); scheduleUIUpdate(); } |
至此为止,已经把 Eclipse 查找框架的流程及涉及到的类进行了详细的说明,相信读者已经有清晰的认识了,但是,由于 Eclipse 中的所有查找功能都共用一个视图,导致这些查找功能不能同时使用,而且,有时候我们可能需要定义自己的查找结果集视图,那么 Eclipse 查找框架中的有些类就不能使用了,如 ISearchQuery,此时,我们不能再给其查找框架了,但是,这个框架的思想我们可以借鉴,读者有兴趣的话,可以开发类似于 Eclipse 的查找框架,但是使用的是我们自己定义的查找结果集视图。
下面给出如何使用自己的查找结果集视图显示匹配项的关键代码,其大致思想是新建一个 Job,在 Job 运行时进行查找,并把查找的匹配项保存起来,待 Job 运行结束后,激活我们自定义的查找结果集视图,最后把结果集填充到该视图中。
提示:Eclipse 查找功能是一个非常典型的 MVC 模式,设计我们自己的查找框架(Search Framework)时,完全可以参考该模式,简洁方便。
public class SearchJob extends Job { protected String fJobName; protected String fTaskName; protected IStatus run(IProgressMonitor monitor) { // 查找代码,保存查找到的匹配项 } protected void performJobDone() { // 启动 UI 线程,激活查找结果视图,并填充匹配项到视图中 } public SearchJob (String name) { super(name); fJobName = name; this.addJobChangeListener(new JobChangeAdapter() { @Override public void done(IJobChangeEvent event) { if (event.getResult().getSeverity() == IStatus.OK) { performJobDone(); } } }); } } |
- 访问 Search in Eclipse Plugin 一文,了解 Eclipse 查找功能的介绍。
- 研读 Interface ISearchResult 一文,理解 Eclipse 查找结果集接口。
- 查看 FAQ How do I write a Search dialog? 一文,理解如何写一个查找对话框。
- 查看 FAQ How do I display search results? 一文,了解如何显示查找结果集到结果集视图。
发表评论
-
以插件的方式把myeclipse安装到eclipse
2013-04-27 16:56 85871, 请注意eclipse版本问题,笔者用的是eclips ... -
eclipse 运行技巧
2012-04-21 10:47 16221, 在有main方法的类上点击,然后可以选择Run As J ... -
eclipse 功能展望
2012-04-20 23:21 895大家都知道, eclipse里面有一个很友好的代码提示功能, ... -
eclipse的老版本下载地
2010-02-05 14:40 988http://archive.eclipse.org/ecli ... -
eclipse 快捷键
2009-11-18 15:43 859转载自 http://spaceflysky-163-com. ...
相关推荐
Eclipse插件开发中的查找(Search)功能及扩展点涉及到以下知识点: 1. Eclipse查找功能的重要性:Eclipse作为一款流行的集成开发环境(IDE),其查找功能对于开发者来说是一个非常重要的特性。它不仅支持基本的...
深入理解这一功能及其扩展点对于插件开发者至关重要,因为这能帮助他们构建符合特定需求的自定义查找功能。在Eclipse 3.4版本中,有四种基础查找功能:文件查找、任务查找、Java查找和插件查找,而在IBM RSA中,这个...
### Eclipse Plugin 开发深入理解查找(Search)功能及其扩展点 #### 深入解析查找功能与扩展机制 查找功能在Eclipse中扮演着至关重要的角色,不仅提供了强大的文本搜索能力,还支持各种复杂的查找需求,如文件、...
Eclipse插件开发是扩展Eclipse功能的重要方式,开发者可以通过编写插件来增加Eclipse平台的自定义功能,从而提升开发效率,定制个性化的开发环境。Eclipse插件开发学习笔记将带领我们深入了解Eclipse插件开发的...
### Eclipse插件开发指南...对于希望深入了解Eclipse插件开发的读者来说,《Eclipse插件开发指南》是一本不可多得的好书,它详细介绍了Eclipse插件开发的各个方面,包括基础知识、开发流程和技术细节等,非常值得一读。
本文将深入探讨Eclipse插件开发的相关知识点,结合提供的"全书分为4篇共24章"的学习笔记和源码,帮助你更全面地理解和实践Eclipse插件开发。 第一篇:基础篇 在这一篇中,你将学习到Eclipse插件开发的基础知识,...
本资源"**Eclipse插件开发扩展点大全(中文)**"正是针对这一主题,提供了详尽的中文指南,帮助开发者深入理解和利用这些扩展点。 Eclipse的扩展点是其插件机制的核心组成部分,它们定义了插件可以插入或扩展的特定...
【Eclipse插件系列——SQLExplorer插件的安装和使用】 Eclipse是一个广泛使用的开源集成开发环境(IDE),尤其在Java编程中应用广泛。为了增强其功能,Eclipse支持安装各种插件,其中SQLExplorer就是一个非常实用的...
从以上内容中,我们可以了解到Eclipse插件开发是一个深入且复杂的主题,它不仅涉及对Java和Eclipse环境的熟悉,还包括对SWT、JFace以及Eclipse插件架构的理解。而对于初学者而言,通过循序渐进地学习和实践,能够...
本资料包包含了从基础到高级的Eclipse插件开发教程,覆盖了开发过程中的关键知识点,旨在帮助开发者深入理解和实践Eclipse插件的开发。 首先,我们来看《Eclipse插件开发 学习笔记 第1篇 开发基础》。这一部分通常...
提供的文档和资料可以帮助开发者深入理解Eclipse插件开发: 1. "eclipse插件开发.doc":可能包含了详细的步骤指南和示例代码。 2. "Eclipse插件开发系列.pdf":可能是一个系列教程,涵盖从基础到高级的插件开发技巧...
4. **扩展点(Extension Points)**:Eclipse通过扩展点允许插件添加新的功能到Eclipse环境中。开发者可以在`plugin.xml`中声明对特定扩展点的贡献,如菜单项、视图或透视图。 5. **插件编程模型**:基于Java的API...
Eclipse的灵活性和扩展性是其主要特点,开发者可以通过安装各种插件来扩展Eclipse的功能,适应不同的开发需求。Eclipse插件开发是提高工作效率和个性化开发环境的重要方式,因此掌握Eclipse插件开发方法具有重要的...
本教程旨在逐步指导初学者进行Eclipse插件的开发,通过实例演示如何利用Eclipse平台的API和扩展点来实现各种功能。 首先,我们要理解Eclipse插件的基本概念。Eclipse插件是基于OSGi模块系统构建的,每个插件都是一...
总的来说,Eclipse插件开发是一项需要深入理解Eclipse平台架构、熟悉SWT和JFace、掌握扩展点和插件通信机制的技术。通过学习和实践,开发者能够充分利用Eclipse的开放性,定制自己的开发环境,提高工作效率。对于...
《Eclipse插件开发(第3版 - 高清)》是关于Eclipse平台扩展开发的一本经典著作,由[美] Dan Rubel撰写,并由陈沛等人翻译,ISBN为978-7-111-30336-7。这本书深入浅出地介绍了如何利用Java、SWT和JFace技术来构建...
如果你在神州数码面试中涉及RCP开发,那么你需要理解如何创建自定义的桌面应用,以及如何利用Eclipse的插件机制扩展功能。 九、熟悉SWT和JFace Eclipse的图形界面构建基于SWT(Standard Widget Toolkit)和JFace。...
Eclipse插件开发是Java开发领域中的一个重要分支,它允许开发者通过扩展Eclipse IDE的功能来创建自定义的工作环境。这份“Eclipse插件开发笔记源码”提供了丰富的学习材料,帮助开发者深入理解并实践Eclipse插件开发...