由于调试flash总是用trace多少有点不方便,于是打算自己做一个类似的信息输出框,这个输出框应该有如下功能:
1.创建简单,添加文本简单,不需要删除操作,但能清空文本。可以限制最大行数,且能动态删除最顶端的多余行。
2.能相应鼠标滚轮事件
3.带有滚动条,滚动条与文本内容联动
带着这些目的,折腾了半天,写了个TextArea类,还是吃了AS3不熟悉的亏,很多细节问题要反复查Adobe的文档,不过总算做完了,下面是完整代码:
package { import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Rectangle; import flash.text.TextField; import flash.text.TextFormat; public class dlTextArea extends Sprite { private var tf:TextField; private var maxline:int = 0; private var slide:Sprite; //滑块 public function dlTextArea(width:int=300,height:int=80) { super(); tf = new TextField(); tf.width = width - 15; //15px是滚动条 tf.height = height; tf.border = true; tf.borderColor = 0x000000; tf.background = true; tf.backgroundColor = 0xffffff; tf.defaultTextFormat = new TextFormat("宋体", 13, 0x000000); tf.selectable = false; tf.multiline = true; tf.wordWrap = true; this.graphics.beginFill(0xd4d4d4); this.graphics.lineStyle(1, 0x000000); this.graphics.moveTo(width - 16, 0); this.graphics.lineTo(width - 1, 0); this.graphics.lineTo(width - 1, height); this.graphics.lineTo(width - 16, height); this.graphics.endFill(); slide = new Sprite(); PaintSlide(0x12aad6); slide.x = width - 14; slide.y = 1; slide.visible = false; addChild(tf); addChild(slide); tf.addEventListener(Event.SCROLL, onWheel); slide.addEventListener(MouseEvent.MOUSE_DOWN, onDown); } //设置做多显示行 public function set maxLine(mx:int):void { maxline = mx; } public function set backColor(col:uint):void { tf.backgroundColor = col; } public function addLine(src:String):void { tf.appendText(src+ "\n"); if (maxline > 0 && tf.numLines > maxline+1) { //1行对应numlines为2 tf.replaceText(0, tf.getLineOffset(1), ""); //删去第一行 } tf.scrollV = tf.maxScrollV; //滚动到末行 if (tf.numLines > tf.bottomScrollV - tf.scrollV + 2) { //动态显隐滚动条 slide.visible = true; }else { slide.visible = false; } } public function Clear():void { tf.text = ""; } //根据颜色填充滑块 private function PaintSlide(col:uint):void { slide.graphics.beginFill(col); if (this.height < 60) { //高度调节 slide.graphics.drawRoundRect(0, 0, 13, 10, 6, 6); }else { slide.graphics.drawRoundRect(0, 0, 13, 20, 6, 6); } slide.graphics.endFill(); } //tf自动滚动,此处更新滚动条位置 private function onWheel(e:Event):void { slide.y = (this.height - slide.height - 2) * (tf.scrollV-1) / (tf.maxScrollV-1)+1; } private function onDown(e:MouseEvent):void { slide.startDrag(false, new Rectangle(width - 13, 1,0, this.height - slide.height-2)); PaintSlide(0x0f8cb0); stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove); slide.addEventListener(MouseEvent.MOUSE_OUT, onUp); //out事件限定在滑块中触发有效 this.addEventListener(MouseEvent.MOUSE_UP, onUp); } //进此函数时,滑块一定在拖动过程中,无需判断 private function onMove(e:MouseEvent):void { tf.scrollV = Math.ceil(tf.maxScrollV * slide.y/(this.height-slide.height-2)); } private function onUp(e:MouseEvent):void { slide.stopDrag(); PaintSlide(0x12aad6); stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove); this.removeEventListener(MouseEvent.MOUSE_UP, onUp); slide.removeEventListener(MouseEvent.MOUSE_OUT, onUp); } } }
第二就是用TextField的numline获得的文本行数比实际行数多1,。
第三是获得整个TextField区域能显示的行数需要计算,即bottomScrollV - scrollV + 1,bottomScrollV是文本框最下面一行的行号,ScrollV则是最上面一行的行号。另外一个属性maxScrollV则是ScrollV最大能达到的行号,不是文本总行数,可以用scrollV = maxScrollV将文本固定在最后一行。
第四是在使用对象的startDrag,需要指定拖动范围,范围矩形的width值是被拖动对象在width方向的变动量,不是限制范围的宽度。在TextArea类中要显示滚动块只能垂直滚动,所以将width设为0。
这个类还不太完善,比如背景透明度,边框颜色都不能改,也不能显示行号。不过要完善也不太难。作为输出框已经够用了。