- 浏览: 225287 次
- 性别:
- 来自: 北京
-
文章分类
最新评论
-
dysking:
SWT 和 JFace -
wangyuhfut:
东西不少啊。学习中。。。
一个比较好、中文说明的emacs配置文件 1 -
pacocai:
呵呵!学习,学习~~~不过要说编辑器的话个人更喜欢用VIM,比 ...
一个比较好、中文说明的emacs配置文件 1 -
zhf1zhf2:
这两百多个记起来也不容易啊
英国人是这样背的! -
regex:
试了两次,都是乱码,版本是23.1.1,看来不适合
汉化 Emacs 菜单
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 的立场。
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 构建全功能代码编辑器: 第 6 部分:Text Ho
2009-05-17 16:17 1337https://www.ibm.com/developerwo ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 5 部分:
2009-05-14 17:32 1277https://www.ibm.com/developerwo ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 4 部分
2009-05-14 17:31 1571Content Assistant developerWor ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 3 部分
2009-05-14 17:30 1352Double Click 和 Triple Click de ... -
实战SWT布局
2008-12-08 00:55 1449标准的SWT布局类 FillLayou ... -
SWT布局
2008-12-08 00:53 1197另外参见:http://java.chinaitlab.com ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 2 部分
2008-11-19 18:12 1282Syntax Highlight developerWork ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 1 部分
2008-11-19 18:11 1237级别: 中级 马 若劼 (maruojie@cn.ibm.c ... -
SWT 和 JFace, 第 2 部分: 简介
2008-11-19 18:06 1211http://www.ibm.com/developerwor ... -
SWT 和 JFace,第 1 部分: 简介
2008-11-19 18:04 1215http://www.ibm.com/developerwor ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 8 部分:
2008-11-19 03:54 0https://www.ibm.com/developerwo ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 10 部分:Text F
2008-11-19 03:50 0https://www.ibm.com/developerwo ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 11 部分:
2008-11-19 03:48 0https://www.ibm.com/developerwo ... -
基于 JFace Text Framework 构建全功能代码编辑器: 第 9 部分:Templa
2008-11-19 03:23 0基于 JFace Text Framework 构 ... -
JFace Text Editor完全掌握之终极指南
2008-06-13 01:57 1945JFace Text Editor是JFace里面一个功能强大 ... -
JFace 视图
2008-06-13 01:49 1199http://blog.itpub.net/post/5050 ... -
SWT的体系结构
2008-06-13 01:18 1268http://flyingbug.blogdriver.com ... -
SWT 全接触
2008-06-13 01:15 1829http://blog.csdn.net/DL88250/ar ... -
细说:AWT,SWT,Swing
2008-06-13 00:42 2104http://www.java3z.com/cwbwebhom ... -
SWT的--键盘事件处理
2008-06-12 21:51 2392http://203.208.37.104/search?q= ...
相关推荐
### 基于_JFace_Text_Framework_构建全功能代码编辑器 #### 引言与概述 _JFace_Text_Framework_(简称JTF),作为Eclipse平台的重要组成部分,为开发者提供了构建高度定制化的代码编辑器的强大能力。JTF不仅支撑了...
- 利用RCP架构组织应用的各个部分,如工作台视图、编辑器、透视图等。 - 调试和测试Eclipse插件,确保其在不同环境下正常运行。 通过深入研究这些实例代码,开发者不仅可以提升Eclipse插件开发技能,还能了解到如何...
3. **代码编辑器**:Eclipse的代码编辑器提供了丰富的代码提示、自动完成、语法高亮、错误检查等功能,极大地提高了开发效率。 4. **构建工具(Builder)**:Eclipse内置了Java编译器,可以自动检测源代码变化并...
4. **透视图(Perspectives)、视图(Views)、编辑器(Editors)和操作(Actions)**:这些是Eclipse插件开发中的基本元素,它们构成了用户界面的主要部分。学习如何创建和定制这些组件以提供特定功能。 5. **调试...
【EMF(Eclipse Modeling Framework)2.2.0】:EMF是Eclipse的一个重要组成部分,它基于 OMG 的 MOF(Meta-Object Facility)标准,提供了创建、存储和操作模型的强大工具。2.2.0版本可能引入了对模型版本控制的支持...
这份"eclipsePluginStudyNoteSourceCode"压缩包提供了从第1章到第24章的Eclipse插件开发学习笔记源代码,涵盖了从基础到进阶的全方面知识。 在Eclipse插件开发中,你需要了解以下核心概念: 1. **插件体系结构**:...
RCP是Eclipse框架的一个重要组成部分,它允许开发者构建功能丰富的桌面应用程序,具有与IDE类似的用户体验。 书中主要涵盖了以下几个关键知识点: 1. **Eclipse RCP基础**:介绍Eclipse RCP的基本概念,包括其架构...
首先,书中会介绍Eclipse RCP的基础知识,包括工作台(Workbench)、视图(Views)、编辑器(Editors)、透视图(Perspectives)等核心概念。这些元素构成了Eclipse RCP应用的基本结构,理解它们对于后续的开发至关...
在《Eclipse插件开发 学习笔记 第3篇 高级进阶》中,开发者将会学习到更多高级主题,比如命令框架(Command Framework)、透视图(Perspectives)、视图(Views)、编辑器(Editors)和操作(Actions)。这些是构建...