`
hqs7636
  • 浏览: 220947 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于 JFace Text Framework 构建全功能代码编辑器: 第 7 部分:

阅读更多
https://www.ibm.com/developerworks/cn/opensource/os-cn-ecljtf7/

Quick Assistant
developerWorks


文档选项
将打印机的版面设置成横向打印模式

打印本页
将此页作为电子邮件发送

将此页作为电子邮件发送


样例代码

级别: 中级

马 若劼 (maruojie@cn.ibm.com), 软件工程师, IBM 中国软件开发中心

2008 年 4 月 24 日

    Quick Assistant(快速帮助)的基本用途是为源代码中的错误提供一些快速的解决方案,它和 Content Assistant(内容提供)虽目的不同,但架构类似。本文介绍如何快速帮助的概念和实现方法。

Quick Assistant

Quick Assistant(快速帮助)的基本用途是为源代码中的错误提供一些快速的解决方案。快速的意思是指这个方案足够简单或者足够模式化,可以由程序帮你自动完成。当然快速帮助是无法解决深层次的问题的,不过一般我们在编写代码的时候,犯的最多的都是一些小错误,所以快速帮助是个非常有用的功能。

在 Java 编辑器中,快速帮助看上去就是下图的样子:

图1. Java 编辑器中的快速帮助
Java 编辑器中的快速帮助

提示:如果还不了解内容提示的概念,参见本系列第四部分了解更多信息。

可见,不管是从名字上,还是界面上,快速帮助都非常类似我提过的 Content Assistant(内容提示)功能。实际上,它们的架构和实现方式也差不多。

快速帮助是基于 Annotation(标注)的,我们已经在本系列第五部分中介绍了如何创建一个标注并显示出来。标注包含一个类型信息,比如错误或者警告或者只是提示。快速帮助的基本想法就是判断光标所在位置有没有标注,如果有则检查标注的类型,如果是你感兴趣的类型,比如错误,则触发快速帮助。

由于其和内容提示的相似性,我就不废话了,让我们直接看看如何实现快速帮助吧。




回页首


实现快速帮助

在目前的例子里,我已经把语法错误显示出来了。因为快速帮助可以针对标注类型来触发,所以我打算增加一种错误类型:Undelcared Variable(未声明的变量),比如在下面的例子中:

清单1. 错误的语法,变量 b 未声明

                a = 3;
a = b;


a 被赋值了两次,第一次是用常量,第二次是把变量b的值赋给变量a。如果根据目前的解析器文法来说,这段代码的语法没有问题,但是语义有问题,因为 b 没有声明过。

对于这种新的错误类型,我会认为用户也许是敲错了变量名,所以会显示出声明过的变量名列表,如果用户选择了一个,则未声明的变量被替换成声明过的变量。对于原来的错误,我不提供快速帮助,这样大家就可以看出差别了。

实现底层支持

要增加错误类型,又需要修改解析器文法,我已经完成这部分,所有未声明的变量都被保存到了一个列表里面。同样,又增强了 SharedParser 以便得到这些未声明的变量。

添加标注类型

我不能还是使用 org.eclipse.ui.workbench.texteditor.error 这样的标注类型,需要有所区别才行。所以我通过 org.eclipse.ui.editors.annotationTypes 扩展点添加了一个标注类型,它的父类还是 org.eclipse.ui.workbench.texteditor.error,这样的话它就可以继承父类的一些设置,不用我去创建 AnnotationPreference 了。扩展的声明如下:

清单2. 错误的语法,变量 b 未声明

               
      <extension
       point="org.eclipse.ui.editors.annotationTypes">
    <type
          name="jtf.tutorial.annotation.undeclared.variable"
          super="org.eclipse.ui.workbench.texteditor.error">
    </type>
</extension>


然后我在 SyntaxChecker 中为每个未声明的变量创建了这个类型的标注,因为有了底层支持,这个过程很简单,就不贴出代码了。我们看看实际的效果:

图2. 新的标注类型:未声明的变量
新的标注类型:未声明的变量

IQuickAssistProcessor

前面两步是把准备工作做完了,现在才轮到真正的接口上场了。IQuickAssistProcessor 的角色和 IContentAssistProcessor 的角色是完全相同的,只是具体方法不同罢了。下面是 IQuickAssistProcessor 的声明:

清单3. IQuickAssistProcessor 接口

               
     public interface IQuickAssistProcessor {
String getErrorMessage();

boolean canFix(Annotation annotation);

boolean canAssist(IQuickAssistInvocationContext invocationContext);

ICompletionProposal[] computeQuickAssistProposals(
IQuickAssistInvocationContext invocationContext);
}


快速帮助比内容提示多了一个上下文相关的接口:IQuickAssistInvocationContext。它可以用来为快速帮助提供一些辅助信息。实际上,内容提示也是需要上下文信息的,但是 JTF 没有另外做一个接口来包装它,如果你要做一个复杂的内容提示功能,往往需要自己来定义一个上下文信息接口。

canFix 方法在内容提示中也没有类似物。这个方法主要是提供给 Marker 系统来使用的,比如下图中所示的右键菜单:

图3. Problem 视图中的右键菜单
Problem 视图中的右键菜单

提示:如果不了解 Marker 是什么,可以参考 Eclipse.org 的文章: Mark My Words

当你在 Problem 视图中右键点击一个错误的时候,弹出菜单中有一个 Quick Fix 的菜单项,如果 canFix()返回 false,那么这个菜单项就会变灰而不可用了。由于我的例子中没有创建 Marker,所以这个方法用处有限。

canAssist 方法给了你一个检查不同上下文的机会,这样你就可以通过不同的上下文信息激活不同的快速帮助了。computeQuickAssistProposals 方法比较简单,除了名字和参数不同,它和内容提示中的 computeCompletionProposals 基本类似。

其它的方法都和内容提示类似,来看看例子中是怎么实现这个接口的,我只列出了 computeQuickAssistProposals,其它方法的实现都非常简短,在此省略。

清单4. ExprQuickAssistProcessor 实现了 IQuickAssistProcessor 接口

               
public class ExprQuickAssistProcessor implements IQuickAssistProcessor {
// other code


public ICompletionProposal[] computeQuickAssistProposals(
IQuickAssistInvocationContext invocationContext) {
// get viewer
ISourceViewer viewer = invocationContext.getSourceViewer();

// get annotation
Annotation anno = getAnnotation(viewer, invocationContext.getOffset());
if(anno == null || !canFix(anno))
return null;

// get doc
IDocument doc = viewer.getDocument();

// get tree
Tree tree = TreeManager.getTree(doc);
if(tree == null)
return null;

// get all declared variables
List<String> variables = TreeHelper.getVariables(tree);

// create proposals
Position pos = viewer.getAnnotationModel().getPosition(anno);
List<ICompletionProposal> proposals = new ArrayList<ICompletionProposal>();
for(String var : variables) {
proposals.add(new CompletionProposal(
var, pos.getOffset(), pos.getLength(), var.length(),
null, var, null, "Add your info here"));
}
return proposals.toArray(new ICompletionProposal[proposals.size()]);
}
}


这段代码和内容提示中的很相似,不同点是这里会去取得当前光标处的标注,然后用 canFix 方法检查标注是否可以被修正。最后,还是返回一个 Proposal 的数组。

配置

最后一步,几乎是把 ExprConfiguration 的 getContentAssistant 方法复制了一遍,只不过那些接口换成了快速帮助的。大家可以对比一下 getQuickAssistAssistant 和 getContentAssistant 有什么不同。提醒大家注意一下:快速帮助并没有和文本类型绑定在一起。这是合理的,因为快速帮助一般是用来修正错误的,在一个错误的源代码里面,可能很难知道某个地方到底应该是什么样的文本类型,因此根据文本类型来注册快速帮助功能是有问题的。除了不同点,看到更多的应该是共同点,比如相似的 Assistant/Processor 结构,相似的信息显示控件。注意,又是信息显示控件,到现在为止,已经有内容提示,快速帮助,文本悬浮和标注悬浮都使用了它。

快捷键处理

在 Eclipse 里面,触发快速帮助的缺省快捷键是 Ctrl+1,和内容提示一样,需要给快速帮助安装一个快捷键处理器,由于我已经在演示内容提示的时候打完了基础,现在只要改改 ExprViewer 的 createHandlers,添加一个 handler 就可以了。

效果

当你将光标放在未声明变量上,再按 Ctrl+1 时,可以看到弹出的框里面列出了所有声明过的变量,选择一个之后,未声明的变量会被替换。如下图所示:

图4. 快速帮助效果图
快速帮助效果图

读者可以尝试修正一下其它类型的错误,不会有反应,因为 ExprQuickAssistProcessor 里面只接受“未声明变量”这个标注类型




回页首


结束语

我没有实现 IQuickAssistInvocationContext 接口,如果是像 Java 编辑器这样复杂的应用,那就很可能需要了,大家可以想想,如何利用好这个接口。本文还提到了在 Problem 视图中有 Quick Fix 的菜单项,大家不妨尝试将编辑器中的错误添加到 Problem 视图中,然后使用快速帮助功能。




回页首


声明

本文仅代表作者的个人观点,不代表 IBM 的立场。
分享到:
评论

相关推荐

    基于_JFace_Text_Framework_构建全功能代码编辑器

    ### 基于_JFace_Text_Framework_构建全功能代码编辑器 #### 引言与概述 _JFace_Text_Framework_(简称JTF),作为Eclipse平台的重要组成部分,为开发者提供了构建高度定制化的代码编辑器的强大能力。JTF不仅支撑了...

    JFace Text Framework教程

    总结来说,IBM的JFace Text Framework教程为开发者提供了一个强大且灵活的工具,用于构建功能丰富的文本编辑器。通过学习和实践,开发者可以掌握如何利用这个框架来提升开发效率,创建出专业级的IDE(集成开发环境)...

    eclipse与MyEclipse代码提示上屏修改后jar包(org.eclipse.jface.text_3.8.101.v20130802-1147)

    标题提及的"org.eclipse.jface.text_3.8.101.v20130802-1147"是Eclipse中的一个关键组件,它负责文本编辑器的相关功能,包括代码提示。 `org.eclipse.jface.text`是Eclipse JFace库的一部分,JFace是构建用户界面的...

    jface.text 3.12.1.zip

    本文将围绕"jface.text 3.12.1.zip"这一特定的Eclipse插件进行深入探讨,该插件是Eclipse文本编辑器的重要组成部分,对于提升Java代码补全体验有着至关重要的作用。 首先,"jface.text"是Eclipse的Java Face (JFace...

    org.eclipse.jface.text_3.12.2.v20180112-1341.zip

    标题中的"org.eclipse.jface.text_3.12.2.v20180112-1341.zip"是Eclipse插件的一个版本,它专注于文本编辑功能。Eclipse是一个开源的集成开发环境(IDE),而JFace是Eclipse的一部分,提供了面向用户的界面组件。...

    org.eclipse.jface.text_3.11.2.v20170220-1911最新修改版

    JFace Text是Eclipse中的一个API,它是构建文本编辑器的基础,提供了文本编辑、搜索、替换、高亮等基本功能。在这个特定的版本中,开发者们对JFace Text进行了优化,特别是对于用户输入行为的处理,比如取消了空格和...

    org.eclipse.jface.text_3.12.2.v20180112-1341.jar

    Eclipse JFace Text是Eclipse IDE中的一个核心组件,它提供了高级文本编辑功能,广泛用于构建用户界面中的文本编辑器。这个特定的版本号表明它是该组件的一次更新迭代,可能包含错误修复、性能提升或其他新特性。 ...

    基于WTP开发自定义的JSP编辑器

    了解和利用WTP中与插件开发相关的其他关键概念,如JFace Text Framework和Eclipse Editor Framework,可以帮助进一步优化编辑器的性能和用户体验。 #### 五、总结 基于WTP开发自定义的JSP编辑器是一个综合性的工程...

    org.eclipse.jface.text_3.8.2.v20121126-164145源码

    深入研究这部分源码,不仅可以提升对Eclipse JFace的理解,也有助于提升开发者在构建文本编辑器组件时的定制能力。同时,这也提醒我们,源码的修改应遵循良好的编程实践,确保软件的稳定性和可维护性。

    org.eclipse.jface.text_3.7.2.v20111213-1208.jar

    《Eclipse JFace Text库与MyEclipse 10.0.0的编辑器功能优化》 在IT行业中,开发工具的效率与便利性对于程序员的工作至关重要。Eclipse作为一款广受欢迎的开源集成开发环境(IDE),其强大的扩展性和自定义能力一直...

    Eclipse SWT/JFace 核心应用的全部源代码

    JFace包括数据绑定、视图管理、对话框和服务等组件,它将许多复杂的SWT操作进行了封装,例如表格和树的数据模型、表单编辑器等。通过研究JFace的源代码,开发者可以学习到如何优雅地组织用户界面,提高代码的可读性...

    org.eclipse.jface.text_3.9.2.v20141003-1326.zip

    这个插件是JFace Text组件的一部分,JFace是Eclipse工作台(Workbench)框架的一个子项目,它提供了基于SWT(Standard Widget Toolkit)的高级用户界面构建工具。版本号"3.9.2"表明这是该插件的第三个主要版本的第九...

    MyEclipse10.7.1代码补全vs风格 jface.text修正版

    因为10.7.1已经完美破解(修正了war文件到处问题),故放上该版本修改过的org.eclipse.jface.text_3.7.2.v20111213-1208.jar 代码补全空格不上屏,适合习惯使用vs等工具的用户 详细描述参见10.0时的插件 ...

    jface源代码不容错过

    7. **视图和编辑器的实现**:Eclipse RCP中的视图和编辑器是通过JFace实现的,源代码能帮助我们理解这两者如何在RCP环境中协同工作。 总之,研究JFace的源代码不仅可以帮助开发者深入理解Eclipse RCP的工作原理,还...

    Eclipse SWT/JFACE 核心应用 配套源代码

    Eclipse SWT(Standard Widget Toolkit)和JFace是用于构建Java GUI应用程序的强大工具,它们与Eclipse IDE紧密集成,提供了一种高效、灵活的方式来创建桌面应用程序。这个压缩包包含的源代码是围绕这两个库的核心...

    Eclipse SWT&JFace开发实战精解 源代码

    Eclipse SWT(Standard Widget Toolkit)和JFace是Java编程中用于构建桌面应用程序的两个关键库。它们都是Eclipse IDE的一部分,提供了丰富的用户界面组件和高级的UI设计工具。本篇文章将深入探讨这两个库的核心概念...

    JFace教程

    **JFace** 是 Eclipse 平台的一个重要组成部分,它提供了一套丰富的 API 来帮助开发者构建基于 SWT(Standard Widget Toolkit)的用户界面。JFace 的核心目标是简化 GUI 开发流程,使开发者能够更加专注于应用程序...

    swt JFace的API文档

    7. **Views and Editors**:JFace 提供了用于构建工作台视图和编辑器的框架,支持多窗口和多页编辑环境。 8. **Control Adapters**:这些适配器类可以添加额外的功能,例如在控件上添加右键菜单。 9. **Bindings ...

    SWT,JFACE核心应用源代码,第二部分.rar

    在"SWT,JFACE核心应用源代码,第二部分.rar"这个压缩包中,我们可以预期找到一系列关于SWT和JFace实际应用的源代码示例。这些示例可能涵盖了如何使用SWT创建基本和复杂的用户界面元素,如何利用JFace进行数据绑定,...

    org.eclipse.jface.text_3.12.0.v20170523-1043.jar

    总的来说,Eclipse JFace Text模块是Eclipse IDE中不可或缺的一部分,它提供了丰富的文本编辑功能,尤其是自动补全特性,大大提升了开发效率。版本3.12.0.v20170523-1043的JFace Text可能包含了一些优化和改进,使得...

Global site tag (gtag.js) - Google Analytics