views:

1218

answers:

2

Flex's text-editing controls (mx:TextField, mx:TextArea) offer functions for doing "stuff" with the selected text (selectionBeginIndex, selectionEndIndex, setSelection), but the text-displaying controls (mx:Label, mx:Text) don't seem to offer anything of the sort.

After some tinkering, I've tried subclassing Label then writing functions which give access to the underlying TextField instance... But even then, setting the selection didn't work!

function get selectionBeginIndex():int {
 // This works
 return this.textField.selectionBeginIndex;
}

function get selectionEndIndex():int {
 // This works
 return this.textField.selectionEndIndex;
}

function setSelection(beginIndex:int, endIndex:int):void {
 // But this has no effect!
 this.textField.setSelection(beginIndex, endIndex);
}

So, is there any better way to access/change the text which is selected in mx:Label and mx:Text controls? Are there "better" controls to use?

+4  A: 

You might be better off using a TextInput with editable property set to false, and borderStyle set to "none" instead of a Label.

Concerning the Text component, that's a little better than Label in certain situations, because it allows the user to select the displayed text with the mouse, and supports multiple lines. But I don't know if you can select the text programmaticaly, though I suspect if you subclassed it, you'd have more success with it than with subclassing Label. Alternatively you could use a TextArea with the same properties I mentioned for TextInput.

To make the TextInput resize based on his text you can override the validateProperties method, and use getLineMetrics() to calculate the needed width:

    public override function validateProperties():void
 {
  super.validateProperties();
  var tm : TextLineMetrics = this.getLineMetrics(0);
  var txtWidth : uint = tm.width + tm.leading + 10;
  this.width = minWidth < txtWidth ? txtWidth : minWidth;
 }

That "10" value might be needed to change based on the font you use probably. If you need the TextInput to resize while you type too, you need to listen to its change event and call validateProperties from the handler.

bug-a-lot
I had considered using that TextInput trick... Thanks for confirming that it will actually work.And, re. subclassing Text VS Label: Text is a subclass of Label, and you can make Label selectable by setting "selectable='true'". Alas, though, subclassing Text didn't help much either :(
David Wolever
The reason I wanted to use Text, though, was that it would grow to fit its input, where TextInput won't (unless there is some method I missed when I was reading about it)
David Wolever
+1 Labels are meant to label other controls and not be interactive elements in an way.
Soviut
Yeah, my bad with Text. I forgot it inherits Label. I've added code to my answer that can be used to resize a subclass of TextInput based on its text.
bug-a-lot
+1  A: 

You might want to use UITextField, the flex version of the flash TextField. This is the object used inside a TextArea for displaying the text. It supports those indexes that you're looking for.

Be warned that styling is a bit weird. "setStyle" does nothing. And you have to override the validateNow function to use the setTextFormat, otherwise, your settings get wiped out. I'm not sure how to use CSS with it, but that wasn't a concern at the time.

Glenn