以下内容都是通过阅读《The Definitive Guide to SWT and JFace》写的。只涉及到语法着色部分,还有内容自动完成,编辑器的Vertical Ruler等内容这里不介绍,Eclipse的插件开发帮助里面介绍的很详细。
TextViewer的输入叫Document, TextViewer在显示文档之前,将对其分割(Partition)成各种类型的区块(Region),每个区块将具有以下属性:区块所使用的字体,字体风格(粗体、斜体、带下划线等等)、区块所在的位置、区块的内容是数字还是括号,区块上下的空格数等,不过TextViewer却无法对不同的区块使用不同的字体大小(这是因为TextViewer的底层是StyleText控件的缘故,一个文档只能使用一种字体大小)
与一般的文字处理器不同,TextViewer没法直接定义各个区块(而文字处理器则可以选中的文字指定为区块从而给其指定各种属性),它是根据内部定义的规则隐式的将文档分割成不同的区块。比如Java Editor,当我们把一段注释添加到文档中之后,编辑器就能将其判断成注释区块,编辑器能做出这种判断就是基于其内部指定的分割规则。在TextViewer中由IDocumentPartitioner 来负责对Document进行解析和分割,一个IDocumentPartitioner 将跟一个Document关联起来,其默认实现是DefaultPartitioner,不同类型的文档需要使用不同的分割规则,显然DefaultPartitioner 无法满足要求,这就需要我们对DefaultPartitioner 的行为进行定制,不过我们一般不这样做,而是通过使用一种所谓的分割扫描器和分割类型来构造DefaultPartitioner 从而达到定制的目的。经过分割扫描器分割后得到的仅仅只是一个很原始的区块,它将是实现语法高亮这样的功能的基础。
Token和分割后得到的各种类型的区块相关联,但是它本身并不包含文本内容,也不具有区块的位置信息,而对于不同类型区块在显示的时候将使用何种颜色这种信息则由Token来提供,从而在整个文档中Token能被重用。
IPartitionTokenScanner 也是一种分割扫描器,当文档被修改时,DefaultPartitioner 将使用自带的IPartitionTokenScanner实现去扫描指定的文档区域来得到相关的Token和Partition信息
一般我们都通过继承RuleBasedPartitionScanner 来实现自己的分割扫描器,通过给扫描器添加各种Rule就可以控制扫描器的分割行为,而每一种分割类型都会有对应的一个Rule, JFace提供了多种Rule,在创建一个rule实例时,需要指定该rule使用的token,对应的字符序列特征,在扫描的时候,当rule找到匹配的文档的时候, 将使用该rule所附带的token对匹配文字进行标识。
要对文档进行分割,需要先创建一个分割扫描器,然后再将分割扫描器作为参数创建文档分割器,接着将文档的分割器设置为前面创建的文档分割器(此时将对文档进行分割操作),最后将分割器与文档关联。
经过分割后的文档将提供丰富的描述信息,不过为了将模型和视图分离,分割后得到的所有区块并不附带视图信息,为了告诉TextViewer如何显示分割后的文档,必须通过给TextViewer指定SourceViewerConfiguration ,而且必须在给TextViewer指定Document之前做这件事。
TextViewer的一个重要功能就是语法着色,要实现这个功能需要三个条件:一个就是表现协调器(Reconciler);一个是与需要着色的分割类型关联的破坏器(Damager)和修复器(Repairer);还有一个就是需要着色的分割类型关联的规则扫描器(RuleBasedScanner,不是分割扫描器)。破坏器用来响应文档的修改,修复器则对改动文档的显示进行调整,因此破坏器和修复器成对出现并与一个表现协调器关联,而协调器可以和多个破坏修复器关联,而每一组破坏修复器都和一个分割类型相关联,破坏修复器只会在他们配置类型的分割区发生变化起作用,破坏修复器包含一个扫描器,它被用来扫描所有相应类型的分区,扫描器中包含的规则将被修复器用来对文本进行着色。
Reconciler,Damager/Repairer, RuleBasedScanner三者之间的关系:给Reconciler设置Damager和Requirer并指定分割类型,当然还要给破坏修复器设置Scanner,而Scanner中也包含一些类,分别是TextAttribute(用来设置着色文本的前景色,背景色以及字体信息),Token(包含一系列TextAttribute),Rule又包含Token和相关字符序列信息,为了将Reconciler与TextViewer关联起来,必须从TextViewer所配置的SourceViewerConfiguration 中来取得Reconciler.