实现Flex的TextArea文本中关键字的高亮显示

最近做的Flex项目中有一个需求,要求在一个TextArea中输入文本时,当文本中出现SQL关键字(如select,from,where等)时,让这些关键字高亮显示。

经过一个下午的研究最终算是基本上实现了,实现的过程就是一个学习的过程。

前几天机器重装了系统,FlexBuilder要重新装,从官网上下了最新版的FlexBuilder4.6装到机器上,算是尝了鲜,不过感觉和4.5差别并不大。接下来便是一步步实现的过程了。

首先要知道使用TextArea的change事件和TextRange类可以动态更改TextArea部分文本的样式。

--------------------------------------------
mx.controls.TextArea.change
当 TextArea 控件中的文本通过用户输入发生更改时分派。使用数据绑定或 ‏‏‎‎ActionScript 代码更改文本时不会引发此事件。

即使 Event.bubbles 属性的默认值是 true,该控件也会在 Event.bubbles 属性设置为 false 时分派此事件。

事件类型:
flash.events.Event.CHANGE
语言版本:
3.0
Player 版本:
Flash 9, AIR 1.1
产品版本:
Flex 3
--------------------------------------------
mx.controls.textClasses.TextRange
TextRange 类提供在 Label、Text、TextArea、TextEditor 和 RichTextEditor 控件中选择和格式化文本范围的属性。
--------------------------------------------
mx.controls.textClasses.TextRange.TextRange(owner:UIComponent, modifiesSelection:Boolean=false, beginIndex:int=-1, endIndex:int=-1)
创建提供文本控件内容子集的新 TextRange Object,包括格式化信息。
参数:
owner 包含文本的控件。此控件必须包含 textField 属性,或者像 RichTextEditor 控件一样包含 textArea属性。
modifiesSelection 是否选择范围中的文本。如果将此参数设置为 true 并且不指定与控件中文本相对应的起始或结束索引,则 Flex 将使用当前文本选项的起始或结束索引。如果此参数为 true,您省略了 beginIndexendIndex参数,并且不存在任何选项,则 TextRange 对象为空。
beginIndex 范围中第一个字符从零开始的索引。如果 modifiesSelection 参数为 false,并且您省略此参数或指定了一个负值,则范围将从第一个文本字符开始。
endIndex 范围中最后一个字符的位置从零开始的索引。如果 modifiesSelection 参数为 false,并且您省略此参数、指定了一个负值或指定的值超出文本结束范围,则范围将以最后一个文本字符结束。
语言版本:
3.0
Player 版本:
Flash 9, AIR 1.1
产品版本:
Flex 3

关键是如何让指定的关键字样式发生变化。首先想到了正则表达式,但由于对正则表达式并不熟悉,所以采取了截取这些字符串,当出现关键字时,更改关键字的样式。

HighlightKeywordTextArea.mxml代码如下:

<?xml version="1.0" encoding="utf-8"?>
<mx:TextArea xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
change="textArea_change(event)" width="100%" height="100%"
creationComplete="textarea_creationCompleteHandler(event)">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;
import mx.controls.textClasses.TextRange;
import mx.events.FlexEvent;
[Bindable]
public var keyArray:ArrayCollection;

[Bindable]
public var keyColor:String = "red";

private var tr:TextRange;

private var crlf:String = String.fromCharCode(13);

private var regEx:RegExp = new RegExp(crlf, "g");

private function setKeyColor(num:int,key:String):void
{
var text :String = this.text.toUpperCase().replace(regEx," ");
var str : String = text.substr(num,text.length);
var strArray : Array = str.split(" ");
var keyIndex : int = strArray.indexOf(key);

if(keyIndex!=-1)
{
if(keyIndex!=0)
{
for(var i:int;i< keyIndex;i++)
{
num += (strArray[i] as String).length+1;
}
}

var length:int = key.length;
tr = new TextRange(this, false, num, num + length);
tr.color = keyColor;

num += (length+1);

if(num<text.length)
{
setKeyColor(num,key);
}
}
}

private function addTextRange():void{
try {
tr = new TextRange(this);
tr.color = "black";
tr.textDecoration = "normal";
tr.fontSize = 20;
for each(var key:String in keyArray)
{
setKeyColor(0,key);
}

} catch (err:RangeError) {

}
}

private function textArea_change(evt:Event):void {

addTextRange();
}

protected function textarea_creationCompleteHandler(event:FlexEvent):void
{
addTextRange();
}

]]>
</fx:Script>
</mx:TextArea>

 

测试主程序HLKeyTaTest.mxml如下:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:components="com.stf.components.*">
<fx:Declarations>
<!-- 将非可视元素(例如服务、值对象)放在此处 -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.controls.Alert;

[Bindable]
public var keyArray : ArrayCollection = new ArrayCollection(["AS","SELECT","FROM","WHERE","AND","OR"]);

]]>
</fx:Script>
<components:HighlightKeywordTextArea width="500" height="300"
keyColor="red" keyArray="{keyArray}"
text="select name as 姓名 from user_info where id='key'">

</components:HighlightKeywordTextArea>
</s:Application>

 

测试效果如下:

 

还存在一些问题:

1.对于很长很长的文本,字符串截取比对效率有点低,有点卡。

2.对于Sql的语的处理还有点弱,比如在引号中如果出现SQL关键字时同样会高亮显示,要是实现SQL编辑中的效果还差的有点远。

 

posted @ 2011-12-29 22:40  STF  阅读(3221)  评论(1编辑  收藏