I'm trying to change the color of all 4-letter words in a spark.components.Label.
It is a chat-like program, where user enters words into the TextInput field, presses ENTER and the lines are appended to the Label (or Text or TextArea or RichText - whatever is suitable here).
I have prepared this simple test case below, it will run instantly in your Flash Build 4.6 and the code to find the words and their indices is already there.
My problem is to figure out how to change the color of text parts programmatically (i.e. by ActionScript 3) and repeatedly, I just can't figure it out despite reading the docs again and again.
Screenshot:
Test.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="400" minHeight="300">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
private const WORD:RegExp = /\b[a-z]{4}\b/i;
public function chat(event:FlexEvent):void {
var line:String = _input.text;
var start:int = 0;
do {
var rest:String = line.substr(start);
var found:int = rest.search(WORD);
// no more 4-letter words found
if (found < 0)
break;
var word:String = rest.substr(found, 4);
trace('word=' + word + ' @ index=' + (start + found));
start += found + 4;
} while (start + 4 <= line.length);
_output.text += (line + "\n");
_input.text = '';
}
]]>
</fx:Script>
<s:Label id="_output" left="4" top="4" right="4" bottom="24" backgroundColor="0xFFFFCC" />
<s:TextInput id="_input" bottom="4" right="4" enter="chat(event)" />
</s:Application>
UPDATE: I'm trying RichText + the code below as suggested by Georgi and see that the pattern replacement has worked (by looking at the trace() output), but get the error:
TypeError: Error #1034: Type Coercion failed: cannot convert "[object TextFlow][object TextFlow]" to flashx.textLayout.elements.TextFlow.
<?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="400" minHeight="300">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import flashx.textLayout.conversion.TextConverter;
private const WORD:RegExp = /\b[a-z]{4}\b/ig;
public function chat(event:FlexEvent):void {
var line:String = _input.text.replace(WORD, '<font color="#FF0000">$&</font>') + '<br>';
trace('line=' + line);
// XXX how to append text here? XXX
_output.textFlow += TextConverter.importToFlow(line, TextConverter.TEXT_FIELD_HTML_FORMAT);
_input.text = '';
}
]]>
</fx:Script>
<s:RichText id="_output" left="4" top="4" right="4" bottom="24" />
<s:TextInput id="_input" bottom="4" right="4" enter="chat(event)" />
</s:Application>
UPDATE 2: If I use _output.textFlow = above then the TypeError goes away. But I need to append the text somehow...
I don't think it's possible with a s:Label
component. You may try using s:RichText
(which, luckily, isn't very different from s:Label
) with appropriate HTML formatting. You'll have to keep the produced HTML and set the textFlow
every time, by using TextConverter
first. Something like this:
<?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="400" minHeight="300">
<fx:Script>
<![CDATA[
import flashx.textLayout.conversion.TextConverter;
import mx.events.FlexEvent;
private const WORD:RegExp = /\b([a-z]{4})\b/ig;
private var output:String = "";
public function chat(event:FlexEvent):void {
output += _input.text.replace(WORD, '<font color="0xFF0000">$1</font>') + '<br>';
_output.textFlow = TextConverter.importToFlow(output, TextConverter.TEXT_FIELD_HTML_FORMAT);
_input.text = "";
}
]]>
</fx:Script>
<s:RichText id="_output" left="4" top="4" right="4" bottom="24" backgroundColor="0xFFFFCC" />
<s:TextInput id="_input" bottom="4" right="4" enter="chat(event)" />
</s:Application>
The code above is not working perfectly, but seems enough to demonstrate the concept.
Edit: Note the "g" flag in the regex to match all the four-letter words.