为什么这个TLFTextField代码只能运行一次?

时间:2013-04-17 20:11:14

标签: actionscript-3 flash flex text actionscript

我需要在用户更改时修改输入TLF文本字段中的文本。例如,每次用户添加或删除字符时,我都会尝试将其设为大写:

import fl.text.TLFTextField;
import flashx.textLayout.formats.TextLayoutFormat;
import flashx.textLayout.elements.TextFlow;

var myTLFTextField:TLFTextField = new TLFTextField();
addChild(myTLFTextField); 
myTLFTextField.x = 10;
myTLFTextField.y = 10;
myTLFTextField.width = 200
myTLFTextField.height = 100;
myTLFTextField.text = "This is my text";

var myFormat:TextLayoutFormat = new TextLayoutFormat();
myFormat.textIndent = 8;
myFormat.color = 0x336633;
myFormat.fontFamily = "Arial, Helvetica, _sans";
myFormat.fontSize = 24;

var myTextFlow:TextFlow = myTLFTextField.textFlow;
myTextFlow.hostFormat = myFormat;
myTextFlow.flowComposer.updateAllControllers();

//--

myTLFTextField.addEventListener(Event.CHANGE, this.onTextFieldChange);
function onTextFieldChange(event:Event):void
{
    myTLFTextField.text = myTLFTextField.text.toUpperCase();
}

//--之前的代码取自TLFTextField documentation,即页面上的第一个示例。

当我尝试编辑文本时,它确实变为大写,但之后文本字段停止响应任何输入,输出显示

  

TypeError:错误#1009:无法访问null的属性或方法   对象参考。在   flashx.textLayout.container :: TextContainerManager / getController()at   flashx.textLayout.container :: TextContainerManager中/ mouseDownHandler()

当我注释掉addEventListener行时,所有内容似乎都正常。

这是否意味着无法对用户输入事件的TLF文本字段中的文本进行更改,就像使用经典文本字段一样?

3 个答案:

答案 0 :(得分:0)

现在无法尝试您的代码所以这是一个疯狂的猜测,但是当您设置文本时控制器似乎消失了。如果你巧妙地这样做会发生什么:

private var m_dontupdate:Boolean;
function onTextFieldChange(event:Event):void
{
  if(m_dontupdate) return;
  m_dontupdate = true;
  myTLFTextField.text = myTLFTextField.text.toUpperCase();
  myTLFTextField.textFlow.flowComposer.updateAllControllers();
  m_dontupdate = false;
}

? (我无法尝试,因为我使用的是FB 4.7,而TLFTextField无处可寻。)

答案 1 :(得分:0)

为什么呢?因为TLF遇到了问题。正如其他人所指出的,在Event.CHANGE处理程序中更改TLF文本会导致第二次调用更改处理程序。在这一点上,事情就崩溃了。

我提出的解决方案类似于@Abe发布的解决方案,但它更通用 - 它不依赖于检查大写字符。您侦听TextEvent.TEXT_INPUT,然后在文本输入处理程序内切换Event.CHANGE侦听器。

import fl.text.TLFTextField;
import flashx.textLayout.formats.TextLayoutFormat;
import flashx.textLayout.elements.TextFlow;
import flash.text.TextFieldType;
import flash.events.TextEvent;

var myTLFTextField:TLFTextField = new TLFTextField();
addChild(myTLFTextField); 
myTLFTextField.x = 10;
myTLFTextField.y = 10;
myTLFTextField.width = 500
myTLFTextField.height = 100;
myTLFTextField.text = "This is my text";
myTLFTextField.border = true;
myTLFTextField.multiline = true;
myTLFTextField.type = TextFieldType.INPUT;

var myFormat:TextLayoutFormat = new TextLayoutFormat();
myFormat.textIndent = 8;
myFormat.color = 0x336633;
myFormat.fontFamily = "Arial, Helvetica, _sans";
myFormat.fontSize = 24;

var myTextFlow:TextFlow = myTLFTextField.textFlow;
myTextFlow.hostFormat = myFormat;
myTextFlow.flowComposer.updateAllControllers();

myTLFTextField.addEventListener(TextEvent.TEXT_INPUT, onTextInput);

var selectionIndex:uint;
function onTextInput(e:TextEvent):void
{
    trace("onTextInput");
    selectionIndex = myTLFTextField.selectionEndIndex;
    myTLFTextField.addEventListener(Event.CHANGE, onTextChanged);
}

function onTextChanged(e:Event):void
{
    trace("onTextChanged");
    myTLFTextField.removeEventListener(Event.CHANGE, onTextChanged);

    // Do whatever you need to do here:
    myTLFTextField.text = myTLFTextField.text.toUpperCase();
    myTLFTextField.setSelection(selectionIndex + 1, selectionIndex + 1);
}

答案 2 :(得分:-1)

首先 - 你在事件监听器中做无限循环!你在事件处理程序中的代码调用它自己! TLF.text = VALUE产生类似TLF.dispatch的事件(new Event(Event.CHANGE));

所以将事件监听器添加到用户操作而不是文本更改!例如。对于KEY_UP

其次 - 更正格式化代码,以便将其应用于新文本:

myTLFTextField.text = NEW_VALUE;

myTextFlow = myTLFTextField.textFlow;
myTextFlow.hostFormat = myFormat;

编辑:为了更加清晰,我添加了完整的代码:

import fl.text.TLFTextField;
import flashx.textLayout.formats.TextLayoutFormat;
import flashx.textLayout.elements.TextFlow;
import flash.events.KeyboardEvent;

var myTLFTextField:TLFTextField = new TLFTextField();
addChild(myTLFTextField);
myTLFTextField.x = 10;
myTLFTextField.y = 10;
myTLFTextField.width = 400;
myTLFTextField.height = 100;
myTLFTextField.text = "This is my text";
myTLFTextField.type = "input";
//allow user to wirte in filed

var myFormat:TextLayoutFormat = new TextLayoutFormat();
myFormat.textIndent = 8;
myFormat.color = 0x336633;
myFormat.fontFamily = "Arial, Helvetica, _sans";
myFormat.fontSize = 24;

var myTextFlow:TextFlow = myTLFTextField.textFlow;
myTextFlow.hostFormat = myFormat;
myTextFlow.flowComposer.updateAllControllers();

//--;

myTLFTextField.addEventListener(Event.CHANGE, wrongHandler);
myTLFTextField.addEventListener(KeyboardEvent.KEY_UP, goodHandler);
myTLFTextField.text = 'TEXT';
//this invoke CHANGE and trace '-' in console

setTimeout(function(){  myTLFTextField.text = 'text';}, 500);
//this invoke CHANGE and trace '-' in console

function wrongHandler(event:Event):void
{
    //myTLFTextField.text = myTLFTextField.text.toUpperCase();
    //myTextFlow = myTLFTextField.textFlow;
    //myTextFlow.hostFormat = myFormat;
    // above code will run infinity loop of changing text! test it by uncomment and comment KEY_UP listener!
    trace('-'); // to see in console when and how many event was triggered
}

function goodHandler(event:Event):void
{
    myTLFTextField.text = myTLFTextField.text.toUpperCase();
    myTextFlow = myTLFTextField.textFlow; // reasign formating
    myTextFlow.hostFormat = myFormat;
    var i:uint = myTLFTextField.text.length;
    myTLFTextField.setSelection(i,i); // move carret to last sign
    trace('+'); // to see in console when and how many event was triggered
}

输出:

  1. -
  2. -
  3. 在字段中写'a'字符后的输出:

    1. -
    2. -
    3. -
    4. -
    5. +
    6. -
    7. 舞台上的结果: TEXTA