ImageVerifierCode 换一换
格式:PDF , 页数:60 ,大小:10.10MB ,
资源ID:13309792      下载积分:12 金币
快捷注册下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

开通VIP
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.zixin.com.cn/docdown/13309792.html】到电脑端继续下载(重复下载【60天内】不扣币)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

开通VIP折扣优惠下载文档

            查看会员权益                  [ 下载后找不到文档?]

填表反馈(24小时):  下载求助     关注领币    退款申请

开具发票请登录PC端进行申请

   平台协调中心        【在线客服】        免费申请共赢上传

权利声明

1、咨信平台为文档C2C交易模式,即用户上传的文档直接被用户下载,收益归上传人(含作者)所有;本站仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。所展示的作品文档包括内容和图片全部来源于网络用户和作者上传投稿,我们不确定上传用户享有完全著作权,根据《信息网络传播权保护条例》,如果侵犯了您的版权、权益或隐私,请联系我们,核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
2、文档的总页数、文档格式和文档大小以系统显示为准(内容中显示的页数不一定正确),网站客服只以系统显示的页数、文件格式、文档大小作为仲裁依据,个别因单元格分列造成显示页码不一将协商解决,平台无法对文档的真实性、完整性、权威性、准确性、专业性及其观点立场做任何保证或承诺,下载前须认真查看,确认无误后再购买,务必慎重购买;若有违法违纪将进行移交司法处理,若涉侵权平台将进行基本处罚并下架。
3、本站所有内容均由用户上传,付费前请自行鉴别,如您付费,意味着您已接受本站规则且自行承担风险,本站不进行额外附加服务,虚拟产品一经售出概不退款(未进行购买下载可退充值款),文档一经付费(服务费)、不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
4、如你看到网页展示的文档有www.zixin.com.cn水印,是因预览和防盗链等技术需要对页面进行转换压缩成图而已,我们并不对上传的文档进行任何编辑或修改,文档下载后都不会有水印标识(原文档上传前个别存留的除外),下载后原文更清晰;试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓;PPT和DOC文档可被视为“模板”,允许上传人保留章节、目录结构的情况下删减部份的内容;PDF文档不管是原文档转换或图片扫描而得,本站不作要求视为允许,下载前可先查看【教您几个在下载文档中可以更好的避免被坑】。
5、本文档所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用;网站提供的党政主题相关内容(国旗、国徽、党徽--等)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
6、文档遇到问题,请及时联系平台进行协调解决,联系【微信客服】、【QQ客服】,若有其他问题请点击或扫码反馈【服务填表】;文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“【版权申诉】”,意见反馈和侵权处理邮箱:1219186828@qq.com;也可以拔打客服电话:0574-28810668;投诉电话:18658249818。

注意事项

本文(java图形编程:JTextXXX文本组件内部原理及JTextPane和JEitorPane专题.pdf)为本站上传会员【曲****】主动上传,咨信网仅是提供信息存储空间和展示预览,仅对用户上传内容的表现方式做保护处理,对上载内容不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知咨信网(发送邮件至1219186828@qq.com、拔打电话4009-655-100或【 微信客服】、【 QQ客服】),核实后会尽快下架及时删除,并可随时和客服了解处理情况,尊重保护知识产权我们共同努力。
温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载【60天内】不扣币。 服务填表

java图形编程:JTextXXX文本组件内部原理及JTextPane和JEitorPane专题.pdf

1、目录第 1 部分:Element 文档结构与 Document 文档模型-2第1章:基础知识-2第2章:java中文本组件各组成部分及主要作用原理-4第 3 章:Element 及 Document 总结-13第 2 部分:JTextPane 和 Attribute 文档属,性-19第1章:属性和属性集-19第2章:创建属性集的两种方法SimpleAttribute类和StyleContext类-24第 3 章:StyledDocument 接 口-26第 4 章:JTextPane 文本组件-28第3部分:Caret光标处理与高亮显示-34第1章:光标Caret接口-34第2章:高亮显

2、示Highlighter接口-38第4部分:EditorKit与键盘输入-42第5部分:JEditorPane与读写文件及打开超链接-47第1章:基础-47第2章:使用JEditorPane读写文件-49第1节:JEditorPane文本组件-49第 2 节:JEditorPane 读取文件原理-49第3节:使用不同的方法加载文档内容到JEditorPane组件-50第3章:保存文件和打开超链接-56第一部分:Element文档结构与Document文档模型(共3章,共17页)第一章:基础知识注意区分这几个单词:Content:内容;Context:上下文,环境,背景;Constants:常量

3、java文档的实现机理java的GUI都是尽量按照MVC(模型-视图-控制器)的原理来实现的,文本组件也不例外。文本组件把模型部分交由 javax.swing.text.Document接口来管理,视图部分交由相应的UI和View接口来管理,文本组件的控制器有Caret(插入 符,就是在文本栏中闪烁的短竖线)接口,KeyMap(键映射,主要用于管理键盘输入),DocuementEvent事件及其监听器 DocumentListener,本文只对文本组件的模型和控制器部分进行讲解,视图部分本文不作讲解。文档的元素(结构),样式,内容在计算机中一般把文档分为3个层次,即结构(比如段落,节,章等),

4、内容和样式(由字体的颜色,粗细等属性组成),在java中,把文档的以上3个层次使用Document接口来集中反应,这样Document接口就成为JAVA众多文本数据模 型的最基础的接口,即所有的文档模型都是从实现该接口开始的,这就是JAVA模型-视图-控制器(MVC)的模型部分的 内容,下面分别介绍这3个层次的作用一、文档的结构:1、结构:比如段落,节,章等,就是文档的结构。2、java使用javax.swing.textElement接口来管理文档的元素(结构)。3、java中把结构称作元素(Element),文档的结构一般指的是像我们平常所讲的段落,章,节等内容,结构理论上来讲 是可以嵌套

5、的,比如一章里面有多少节,一节又有多少段落,因此,java文档的结构采用的是树型数据结构来管理 这种嵌套的结构,即所有结构都有一个根结构,然后根结构下有很多子结构等;同时在结构中的文档还具有样式,比如章节的内容一般使用大号粗体字表示等,因此文档的结构一般都需要关联与之相联系的文档的样式(或属睦。4、注意:java把文档的结构称为元素Element,这样称呼是有一定道理的,因为java的文档除了要处理文字内容之外,还要处理诸如图标、组件等这样的东东,因此java把这些结构统称为元素,同时java把元素分为很多类型,比如 把文档的结构分为,内容、段落、节3种类型,同时把支持的图标、组件等也单独成为

6、一种元素类型,而且用户还 可以实现自己添加的元素类型二、文字的属性和属峥:1、文字的属性:比如文字的大小,粗细,字体,颜色等,其中的每一个都是文字的一个属性。2、java 使用 javax.swing.textStyleConstants 类来管理单一的文字属性,使用 javax.swing.textAttributeSet 接口 来管理 多个属性组成的集合,即属性集。*3、属性集:就是单L的集合;二般一个文档中的文字包括了文字的多个属性,比如一个为4号粗体红色的字,这 里就包括的文字的3个属性,即字体大小4号,粗体,颜色为红色这三个属性,这多个属性就构成了属性集。3、注意:属性集一般都是与文

7、档的结构(元素)相关联的,也就是说,一个标题段落的文档,包含有属性集(比如,粗体,1号字体,红色等)。三、文档的样式或称为风格(Style):1、文档的风格就是文字属性的一个集合,这一点和属性集是相同的,在java中风格与属性集不同的是,风格为属性集 取了一个名字,这是风格和属性集的不同。2、属性集在java中是使用AttributSet来管理的,但AttributSet没有为属性集取一个名字提供方法,也没有提供向属性 集添加属性的方法,而MutableAttributeSet提供了向属性集添加属性的方法,Style接口在MutableAttributeSet接口 的基础上,提供了为属性集命名

8、的方法,即为属性集取一个名字。四、文档的内容:1、文档的内容就是我们想要存储的文字信息,在这里就需要了解一下文本编辑器的缓冲方式和原理了,在计算机中,文本编辑器一般使用4种缓冲区之一作为其存储文档的缓冲区,即字符数组缓冲区,字符串缓冲区,链表缓冲区,间隙缓冲区,下面分别介绍这4种缓冲区的原理及特点2、java使用javax.swing,text.AbstractDocumentContent接口来管理文档的内容,其直接实现该接口的类是 javax.swing.textStringContent(字符串缓冲区)和 javax.swing.text.GapContent(间隙缓冲区)3、字符数组缓

9、冲区即使用普通的字符数组char作为缓冲区,这会面临一个问题:当在数组中插入或删除一个字符时,会导致数组的 后半部分的移动,一个极端的例子是在数组的开头插入一个字符将导致后面的Length-1的字符逐一向后移动一个位 置。很明显地,这将导致严重的性能问题。4、字符串缓冲区(java有采有这种方式)为了解决字符数组缓冲区的问题,我们可以使用字符串String来作为其缓冲区,其实String具有不变性,表面上的变化实质是通过创建新字符串来实现的,频繁的创建新对象将使用不少的资源。5、链表缓冲区链表的插入和删除操作代价是很小的,所以也许可以将缓冲区中的字符作为链表的节点来构造一个链表缓冲区,但 如果

10、编辑的文本较多时,即链表较长时,迭代到链表的指定位置处所花的时间将是难于忍受的,也就是说它不能像 数组那样快速地索引。5、间隙(gap)缓冲区(java有采用这种方式)1)、这是一种较好的方式。间隙缓冲区其实也是一个数组,但我们会想办法来尽量避免频繁的字符移动。间隙缓冲 区的原理是在插入符号(要插入或删除字符的位置)的左侧增加一些“间隙”,一般我们会分配一个合理长度 的间隙,比如分配间隙的长度为256,那么当我们在向文本中插入一个字符时,就会相应的减少一个间隙,将 256个间隙的其中一个替换为要插入的字符,在这中间,很明显没有出现字符串的移动,也没有创建新的元素,因此这样的代价是比较小的,只有

11、当插入的字符过多,导致“间隙”长度接近。时,我们才有必要重新分配空 间以便将“间隙”回复到一个合理长度,同样只有当删除的字符过多,导致“间隙”过大的时候,我们才有必 要“缩紧”数组以求占用更少的空间。很明显这种分配次数相对于插入的次数是微不足道的。2)、比如编辑器中的文本为“Gap text buffer,并且插入符号(当前编辑位置)在字符串“text”后面,那么它在 缓冲区中的布局是这样的:“Gap text Illi buffer”,其中的“叫”就是我们插入的“间隙”。当我们要在当前编辑 位置片新插入一个字符x(text”后面),那么编辑器中的文本变成“Gap text x buffer”

12、而缓冲区中的布 局变成:Gap text xlll buffer其实我们可以发现此次插入操作并没有字符的移动(这是普通字符数组所不能达 到的),没有新字符串的创建(这是String所不能达到的),而它仅仅是将该字符数组中的“间隙”的第一个I 替换成X、即仅仅是“间隙”变短了。3)、同样的道理,我们发现想删除X,这个字符,只需要执行上述过程的逆过程,将该字符数组中的“间隙”变 长,将字符X,替换成就可以了。可以发现在间隙缓冲区中,大多数的插入和删除操作仅仅导致了“间 隙”的伸长或缩短,而缓冲区中的其他位置却是不发生任何变化的。第二章:java中文本组件各组成部分及主要作用原理组操作的集合(其实

13、和 快捷键相类似),比如使 用ctrl+c进行复制等,就是编辑器的内容。当 向文本组件输入内容 时,JTextComponent 会 负责将内容插入到模 型,最后再由模型通知 视图进行更新档内容的存储在 AbstractDocument 抽象 类中,同时此类还负责 在内容发生更改时,产 生 DocumentEvent 事件 并通知所有已注册的监 听器当向文本插入或删除内容时,模型会产生DocumentEvent事 件,并通知视图对文本组件的外观进行更新,这样我们就能 在屏幕上看到我们所做的更新了,视图是很复杂的组件,它 不是单单由一个View类组成的,而是由很多部分组成,每 一部分负责绘制其自

14、已的部分视图编辑器(EditorKit)属性 AttributeSetjava文档的各组成部分及各模块的主要作用图当我们向文本组件插入内容时,其所有键盘事件是由JTextComponent负责处理,接收到事件后JTextComponent会检查 输入的按键是否与某一操作关联(具体参看本文后下内容若是则执行这一操作,若不是,则将内容插入到文档模型,文 档模型调用相关方法插入输入的字符,然后通知视图对进行更新以显示文档,视图根据文档模型所关联的元素(结构)对其进行更新,注意:JTextField,JTextArea组件,包含一个段落元素(对于无格式组件就是根元素),及一个或多个内容元素,而没 有相

15、关联的属性,在更新这些组件的视图时,视图只需把每个元素(结构)映射到屏幕上的一行即可。一、文档的模型(Document)、视图(View)、控制器(DocumentListener)三者的关系我们知道当文档的内容发生改变时,文档的模产生一个DocumentEvent事件,并通知所有已注册的 DocumentListener监听器,然后通知视图对其外观进行更新,这样就将所更新的内容显示在屏幕上了,这里要注意,我们向文档中插入的数据是保存在实现了接口 AbstractDocument.Content的类中的,而这些数据是与外观呈现出的 样式无关的,也就是说,即使屏幕上看不到我们插入的数据(即视图未

16、更新),但文档的内容依然被插入了,只是屏 幕上没显示出来而已。二、Document 和 AbstractDocument1、java使用javax.swing.text.Document接口来实现文档的模型,Document接口的功能就是提供一种基本的途径来访问 和管理控彳牛中的数据 每个文本组件都有自己的Document,若在创建文本组件时没有提供自己的Dcocument,则 java会使用一个默认的实现,对于JTextField和JTextAre这个默认的实现是PlainDocument类。2、Document接口不管理文档的内容部分,文档的内容部分由javax.swing.text.Ab

17、stractDocument抽象类来管理,该类实 现了接口 Document,同时定义了自己的一些接口,其中AbstractDocument.Content接口便是用来管理文档的内容的。AbstractDocument抽象类,除了 Content嵌套接口之外,另外还有6个嵌套接口,他们都定义了不同的功能。3、所有的文本组件都是基于AbstractDocument抽象类的,该类提供了对Document接口的一个基本实现,但我们无法 直接创建该类,因为AbstractDocument是一个抽象类,同时其构造函数也是受保护的,因此要创建一个Document 一般都是创建一个PlainDocument

18、或DefaultstyleDocument类(这两个类都继承自AbstractDocument,且是一个完整 的类),或继承AbstractDocument抽象类,来后行开发,一般未继承Document接口来开发自定义的文档模型。4、通过共享相同的文档模型可以实现两个文本组件内容的同步,比如JTextArea jtal=new JTextArea();JTextArea jta2=new JTextArea();jta2.setDocument(jta 1.getDocument();将文本组件jtal 的模型作为jta2 的模型,这择设置之后,在jtal中输入删除或复制等内容时,组件jta2

19、也会作同样的操作,在jta2中作相同的动作时jtal也会进行相应的 操作。三、文档的内容文档的内容使用AbstractDocum6nt中定义的一个内部接口 Content来实现的,在编写自定义的文档模型时,一般都 不继承此接口,而是直接使用java中定义的两个完整的类,即GapContent(间隙缓冲存储)和StringContent(字符串 缓冲),什么是间隙缓冲和字符串缓冲存储请参看本文相关内容。四、文档的模型(Document)、元素或结构(Element)、属性集(AttributeSet)三者的关系1、文档的模型,其作用就是负责管理文档中的数据,同时每个文档模型必须与一个文档结构相关

20、联 也就是说一种模 型必须有一种结构,同时文档的结构一般有一种属性因此结构和属性集关联,这样文档的模型就把内容,结构,属性关联在一起了。2、模型、结构(元素)、属性集三者之间的关联模型、元素、属性集三者的关联3、模型(Document)使用Element getDefaultRootElement。方法来与文档的元素(结构)进行关联,元素(结构)Element使用 Document getDocument()方法来与文档的模型进行关联,从上图中可以看到,模型和元素结构)之间的关联是双向关 弹的。4、元素(结构)Element使用AttributeSet getAttributes。方法来与文档

21、的属性集相关联,可以在此方法中反回null,但此 方法从不会反回null,若反回的是null,此方法会反回一个空的属性集的引用。5、注意:每个文档必须有一个根元素(RootElement)。6、java创建文档的大致步骤(对继承Element和Document接口实现自定义的类时,这里的讨论会有帮助,这里只讨论 模型、元素之间的执行顺序)1)、创建文本组件时,首先会创建一个文档模型(Document),这时会执行实现了模型接口的类中的构造方法,然后 调用模型中的getDefaultRootElement。方法以获得模型的根元素,然后转到相应的元素接口,并调用Element接 口中的getDoc

22、ument方法以反回相关的模型,在这里要注意:在调用Element中的getDocument方法之后,程 序会不停的一直调用 Element 中的一些方法,比如 getDocument(),getElementCount();getElement(int index);getElementIndex(int offset)等。2)、每当我们删除文档的内容或在文档中选择内容,点击鼠标时,都会再次调用Document中的getDefaultRootElement()方法。使用键盘移动光标和向文档中插入内容不会再次调用getDefaultRootElement方法。五、文档内容的更新(若要继承Abs

23、tractDocument来实现自定义的模型时,这里的讨论会有帮助)1、主要讲解Document 接 口中的 insertstring,remove,replace 三个方法和 AbstractDcoument 抽象类中新增的 insertUpdate 和removeUpdate两个方法2、JTextComponent负责所有的按键事件,当向文本组件输入内容时,JTextComponent会负责将内容插入到模型,最后 再由模型通知视图进行更新3、文档内容的更新内容更新是通过Document 模型中的 insertString(iiit offset,String s,AttributeSet

24、as),remove(int offset,int len);和 replace(int offset,int len,String s,AttributeSet as);三个方法来分别实现文档的插入,删除和替换三个操作。这3个方 法中的参数都能得到正确的值(是怎样得到正确值的,我们不需要知道,这是java接口内部实现的,我们只须只管 使用即可),也就是当我们向文档中输入内容时,insertstring中的参数s就是我们所输入的字符,而。ffset就是我们 输入字符的位置,同理remove和replace中的参数 也能正确得到我们所要的值,其中remove中的参数offset可以 知道我们要删

25、除内容的起始位置,而len就是要删除的长度,换句话说,也就是我们选择了一个连续的块时,比如 选中从位置3开始到5的3个字符,这时remove中的offset参数的值就是3,而len的值也是3,若只选中2个字 符,则len的值是2,replace中的offset和len参数与remove相同,而参数s就是我们输入的字符串;至于以上3 个方法中的参数是怎样得到这些正确值的,我们不必去知道,这就是Document接口提供给我们的功能。4、向文档插入内容是通过模型的insertString(int offset,String s,AttributeSet as);方法来实现的,因此在我们实现自定义 的

26、文档时,应重写此方法,而且应在此方法里产生一个DocumentEvent事件,并通知所有已注册的DocumentListener,同时还得编程来让视图更新外观,来响应已向文档中更新了内容。5、文档内容的删除使用的是remove(int offset,int len)来完成的,与insertstring相同,我们编写此方法时,也必须得产 生一个DocumentEvent事件,并通知所有已注册的DocumentListener,同时还得编程来让视图更新外观,来响应已 向文档中更新了内容。6、文档内容的替换使用的是replace(int offset,int len,String s,Attribu

27、teSet as);方法进行的,替换的方法因算法而异,在 AbstractDocument中采用的是删除并插入,也就是替换选定的内容时,首先会调用remove方法删除选定的内容,然后再调用insertstring方法向文档中插入内容。其实在向文档中插入内容时,insertstring方法是通用replace来调 用的,也就是说,插入内容时不会直接调用insertstring方法,而是首先调用replace方法,然后再通过replace中调 用insert方法。与insertstring相同,我们编写此方法时,也必须得产生一个DocumentEvent事件,并通知所有已注 册的DocumentL

28、istener,同时还得编程来让视图更新外观,来响应已向文档中更新了内容。7、因为产生正确的DocumentEvent事件,并编写代码让视图进行更新是很复杂的事情,再加上Document不管理内容 部分,最主要的问题是编写让视图进行更新的代码比较复杂,因为视图得不到更新,我们在屏幕上就看不到我们对 文档所做的更改,这样就没有达到我们的目的,文档的视图View部分本文不做研究,因此,若从Document接口来 实现自己的模型是有一定难度的。因此我们一般都是使用继承自AbstractDocument的类来开发自己的文档,因为 AbstractDocument是一个真正的类(即使是抽象类),因此他提

29、供了一些代码,比如AbstractDocument中的insertstring 方法,就能产生正确的Document承件并向所有注册的DocumentListener监听器进行广播,同时能通知视图对组件 的外观进行更新,因此我们在重写AbstractDocument中的insertstring方法时,一般都会调用父类的此方法,即加上 语句 super.insertString(.);同理,remoe 和 replace 方法都是如此。8、在AbstractDocument 卡,除以上3个方法外,还新增了 insertUpdate和removeUpdate两个方法,这两个方法都使用 两个参数,其

30、类型分别是 AbstractDocument.DefualtDocumentEvent 和 AttributeSet,但 AbstractDoucment 没有对此方 法作有意义的实现,而PlainDocument等继承自AbstractDocment的完整类都对其作出了完整的实现,这两个方法的 主要作用有2点,第一:就是当我们在文档中增加或删除内容时,为其创建元素(结构)Element,第二:使用文档的 修改记录来更新DefaultDocumentEvent事件,以便其他组件能够更新其模型视图,通过此记录,可以进文档的操作 进行逆转。这2个作用中的第1个作用是很重要的(第2个作用不作讨论),

31、以无格式文档为例,若我们在文档中按 下回车键时,则需要增加新的元素(结构)Element,若不这样,则在JTextArea这种多行文本的组件中,文本将无法 进行换行,因为在无格式文档中,文档的元素被分为2种类型,一种就是根元素(RootElement),根元素管理的范围 一般是从文档的开始直到结尾,而真正能反应文档实质的还是根元素下面的子元素,这子元素在无格式文档中一般 被称为内容(content)元素,一个内容元素管理文档中的一行,若增加一行就得增加一个内容元素,若增加了一行而 没有增加内容元素,则文本会显示在文档中的同一行上,也就是文档没有换行,因此在多文档组件中,要实现文档 的多行处理,

32、还得重写此方法,并在文档需要时增加或者减少内容元素,在AbstractDocument中没有对此方法作有 意义的实现,因此,若是继承自AbstractDocument来实现自己的文档,并且要处理多行文本时,还得编写程序,让 内容元素在需要时增加或减少。有关元素Element的讨论,在后文会有详尽的描述。六、元素或结构(Element)1、结构:比如段落,节,章等,就是文档的结构,在java中使用元素,在下文所说元素都是指的结构。2、java使用Element接口来实现文档的结构。3、Element使用其方法AttributeSet getAttributes。来与文档的属性集进行关联,因此若需

33、要将自定义的属性集关联到结 构,此方法就很重要。4、结构:是可以嵌套的,比如一章里面有多少节,一节又有多少段落,因此,java文档的结构采用的是树型数据结构 来管理这种嵌套的结构,即所有结构都有一个根结构,然后根结构下有很多子结构等;同时在结构中的文档还具有 样式(或称属性集),比如章节的内容一般使用大号粗体字表示等;5、一个元素(结构)表示的是文档中具有相同属性的一个连续的块,因此每个元素都有一个作用范围,这是通过Element 接口中的getStartOffset和getEndOffset方法来实现的,注意:这两个方法反回的值,对文档影响很大,比如反回的 作用范围只是3-8,而其他范围没有

34、元素与之相关联,则在文档组件中,将只有偏移3-8的字符会显示,因为只有 他们有元素。6、分支元素与叶元素:元素是按树型结构来存储的,因此元素分为分支(Branch)元素和叶(Leaf)元素,分支元素可以包 含其他的元素(即可以有子元素),而叶元素则不能有任何其他元素,分支元素不能用来描述文档的内容,只有叶元 素才能描述文档的内容,因而分支元素可以没有相应的作用范围,他的作用范围隐含地由其所有的子节点所覆盖的 范围来确定,当然分支元素的子节点可以是分支元素也可以是叶元素。使用Element中的getParentElement可以设 置当前元素的父元素。使用isLeaf方法可以设置当前元素是否为叶

35、元素。七、继承Element接口实现自定义元素1、以下7个方法是自定义Element的关键,下面讲解一下应怎样重写他们,以及他们之间的关系。1)、Element getElement(int index)反回指定索引处的元素2)int getElementIndex(int offset)反回文档中指定偏移处所关联的元素的索引3)int getElementCountQ反回拥有的子元素数,若是叶元素则反回0。4)、boolean isLeaf()是否是叶元素5)、Element getParentElement()反回父元素6)、int getEndOffset()反回结束位置7)、int g

36、etStartOffset()反回开始位置2、getElement,getElementlndex,getElementCount三个方法主要是针对分支元素而言的,因为只有分支元素才会拥有 多个子元素,因此getElementCount才有意义,同时因为分支元素有多个子元素,才会为每个子元素都保留一个索 引号,每个索引号对应一个子元素。getElementlndex方法不管是对分支元素还是叶元素都适用,他反回的是文档中 指定偏移处所关联的元素的索引。3、getStartOffset和getEndOffset两个方法反回的值直接关系到叶元素所影响的文档的范围,叶元素影响的范围就是从 getStr

37、artOffset开始至U getEndOffset结束的这段文档的内容,这两个方法对于叶元素而言相当重要,因为对文档真正 起作用的是叶元素,因此叶元素对文档所影响的范围就很重要,而对于分支元素而言就不这么重要,因为分支元素 的作用范围是由其所有子元素所共同作用的。4、注意:JTextField,JTextArea组件,包含一个段落元素(对于无格式组件就是根元素),及一个或多个内容元素,而 没有相关联的属性,在更新这些组件的视图时,视图只需把每个元素(结构)映射到屏幕上的一行即可。5、下面以无格式单行文本和多行文本来说明以上7个方法的关系1)、无格式多行文本就是一个元素管理一行的文档,一般行都

38、以回车作为结束(注意:是否使用回车作为换行的标准,主要与元素Element的实现有关,在本文的例子中不一定能以回车换行),以下都以最简单的形式讨论,也就是 所有的元素只分2个层次,第一层为根元素,所有的叶元素都是根元素的子元素,每个叶元素都管理文档中的 一行内容。在无格式文档中,一般把管理一行内容的元素称为内容元素,把管理整个文档的元素称为段落元素,因此,一个文档只有一个段落元素,它就是根元素,而内容元素可以有多个,他们都是段落元素(根元素)的子元 素。2)、int getElementCount。方法A、此方法反回分支元素中子元素的数目,而且必须反回文档所需要的子元素的数目,而且必须随文档的

39、需要而 增加或减少,反回的子元素的数目既不能多也不能少,当然此方法是相对于分支元素而言的,对于叶元素而 言不会包含任何子元素,所以叶元素只需反回0。B、在无格式多行文本中,因为文本的一行就需要一个元素,文本有N行就需要N个元素,因此这时的元素必 须是有层次结构的,也就是这N个管理N行的元素,至少都需要一个公共的父元素,而这个父元素一般都 作为模型的根元素,在最简单的情况下,这N个元素都是叶元素,因为叶元素才是直接管理文档内容的元素(前面已讲过),那么在重写这N个叶元素的共有父元素(以后就称为根元素)中的getElementCount方法时,就 必须反回值N,因为他有N个子元素,同时随着文档内容

40、的更新,这个N值必须随文档行数的需要而增加 或减少,当然这就是我们编写自定义Element管理多行文本重写此方法的难点所在了,因为若文档的行数超 过叶元素的数目的话,则就会有一些行没有元素所关联,这样这些行的内容在屏幕上显示就有一些问题,若 文档的行数比叶元素的数目少的话,则文档在屏幕上会比实际上多显示出几行(当然,多显示的行必须得有 相应的元素与之关联),而这多出来的几行无法获得光标且无法进行编辑,多出来的这几行的内容就得看关 联到内容的叶元素了,因此getElementCount方法必须反回文档所需要的叶元素的数目,而且必须随文档的 需要而增加或减少,即不能反回多也不能反回少。C、对于只有

41、一个根元素的单行文本而言,在根元素中的getElementCount只需反回1即可,因为单行文本只需 要一个叶元素与之关联。D、对于叶元素而言,因为叶元素没有子元素,所以getElementCount方法应反回0。E、如果所有元素(包括根元素)中的getElementCount都反回0,那么就说明文档没有任何元素与之关联,这时我 们就无法获得文档的元素(结构)从而无法在屏幕上显示文本。F、对,只有一个元素的文档(即只有根元素),此方法必须反回1,若不然就没有元素与文档关联,从而就无法 显示文本。3)、Element getElement(int index)方法:反 回索引 index 所对应

42、的元素。A、此方法主要用于分支元素中,分支元素为其自己的每个子元素都编了一个号,这个号就是以索引(index)的形 式存在的,第1个子元素的索引为0,第2个为1,第3个为2.以此类推,因此分支元素有多少个子元素其 索引就有多少个,只不过索引从0开始。B、在多行文本中,因为每一行就有一个叶元素与之关联(具体请参看本文相关内容,因此其根元素(以最简单的 形式讨论,根元素就是所有叶元素的父元素)所对应的每一个索引都要反回一个叶元素,因此每个索引都对 应于文本中的一行 比如索引。对应于文本的第1行,索引1对应第2行,只是索引是从0开始,若索引0 所对应的元素为A,则第一行将使用元素A来与文档内容相关联

43、若某一个索引没有相对应的元素,则这一 行就无法显示内容,比如索引。无对应的元素,则第一行将无法显示内容(因为第一行没有元素相关联);同 样对于大于子元素数目的索引则反回null oC、对于只有一个根元素的单行文本而言,若要显示文档的内容,那么至少应在根元素的getElement方法中为索 弓I。反回一个元素,那么文档才会显示第一行的内容。D、在多行文本中,子元素此方法可以反回null,但根元素必须反回指定索引处所关联的元素,若反回null则文 档将无法显示文本,因为没有任意一行有元素相关联。E、对于只有一个元素(即根元素)的文档,此方法必须反回索引所关联的元素,也就是此方法必须反回一个Ele

44、ment,而不能反回null,若反回null则文档将无法显示文本,因为没有文本与元素关联。F、我们知道在多行文档中,文本的行数是随修改而变化的,而行数的增减都对应索引号的增减,而每增减一个 索引号都意味着元素的创建和删除,因此叶元素的数目会随文档的改变而发生变化,索引的大小也会发生变 化,当叶元素减少时,我们应在相应的索引下反回null,当叶元素增加时,我们应在相应的索引下增加叶元 素,因此,对于多行文档重写Element时,这里就是难点所在了。4)、Element getElement(int index)与 int getElementCount。和元素作用范 H(getStartOffs

45、et 和 getEndOffset)的关系A、在多行文档中,不同的元素作用范围是不同的,而且他们的索引也是不同的,比如与索引为0(第一行)所关 联的元素的作用范围是0-8个字符,使用的是元素A,这样可以显示第1行的0-8个字符;若从第9个字符 起,文档进入第2行,这时这一行的元素必须关联的超始范用是9,而且应该让索引1与此元素相关联,若 我们还是使用的元素A,这时就会第1行和第2行显示相同的内容,因为他们使用的是相同的元素;同时在 文档内容中增加了行数那么根元素的getElementCount也要相应的增加1,比如若有2行,则getElementCount 应反回2,若反回1的话,就算索引1有

46、元素与之关联,也不会显示第2行的内容,因为程序会认为此文档 只有一个子元素,索引的最大值也就是0,而索引0只与第一行相关联,这样就只会显示一行。B、最简单的方法就是4根元素的getElement方法中直接反回一个元素,这样不管索引为多少都会反回一个与索 引相关联的同一个元素,比如在根元素内Element getElement(int index)return new C();其中假设C是实现 了接口 Element的一个类 但这样做无法让文档正常显示,因为此方法都是反回的相同的元素,因此这个元 素的作用范围都是相同的,若根元素的getElementCount方法反回的是2的话,则会在2行上显示

47、相同的文 档内容,而且除第一行之外的其他行都不能编辑,当然,若getElementCount反回的是3,则会显示相同内容 的3行文本,反回4就会显示4行,但都只有第1行是可编辑的,因为他们使用的都是相同的元素来管理相 应行,比如若getElementCount反回2,就意味着根元素包含有2个子元素,在元素中搜索索引为1(就是第2 行)所关联的元素时,因为反回的元素是与第1行是相同的,因此第2行就使用的是第1行的元素,显示的 内容就和第1行相同了。这也说明了,getElementCount反回的数目一定要随文档的内容变化而作相应变化,行数增加时getElementCount应增加1,减少时应减少

48、1,而不能对此方法随便反回一个任意的数目。当然,若getElementCount反回的数目比实际的元素数目多,但相应的索引没有与此相关联的元素时,就不会出现 上面反回多少就有多少行内容的情况。5)、int getElementIndex(int offset)方法与多行文本输入回车换行的问题A、假设有文本,内容为abcdefg,这时我们的根元素中的getElement可以只反回一个元素,假设为A,getElementCount只需反回1即可,这时元素A的关联范围可以是文本的整个范围。B、比如我们在文本内容为abcdefg的d之后按下回车,这时应使文本换行,而且第2行的内容应是efg,这对 于根

49、元素Element来讲,必须更新其中的一些方祛,这丝方法如下:C、getElementCount应反回2,因为现在需要2个元素来显示2行内容,同时getElement(int index);应使index为 0时,关联一个元素,这个元素假设为A,还应使index为1时关联一个元素,假设为B,也就是getElement(int index)中的内容大 至如下.if(index=O)retum A;if(index=1)retum B;.这样元素A就管理第1行,其关 联的范围应是0-4,元素B就管理第2行,当然,我们还得修改元素A和B的getStartOffset和getEndOffset 来改变

50、他们的关联范围。D、同时int getElementIndex(int offset)也得进行修改,若文本的范围在0-4之间,应使getElementlndex(int)反回0,这样也就是说0-4个字符是由索引为0的元素所管理如 同理文本的范围在5-末尾应反回lo如果 getElementIndex(int offset)反回不正确的值,会使文本内容显示错误,比如在范围0-4时反回1,这时会使0-4 个字符使用索引为1的元素,也就是元素B来管理第1行的内容,而元素B关联的范围是5-末尾,因此0-4 个字符就不会被显示,因为不在元素管理范围之内,因此当我们更改文本的内容时,getElementI

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服