Multiline Buttons
Someone recently asked about having the label of a radiobutton wrap onto more than one line. Maybe it just got lost in FlexCoders traffic because I'm sure others have already solved this, but I put together this version out of my own curiosity. The pattern can be re-used for Button and CheckBox as well. The usual caveats apply.
You'll notice that I used "undocumented" methods to accomplish this, so it might break in some future release of Flex. However, this is really intended to be another example of subclassing and illustrate that by knowing the underlying base class you can usually tweak things the way you want them.
Now you may ask, why doesn't this functionality come built-in with Flex? The answer is that text-flow is slow and doesn't really work well with the Flex layout system. That's because there really is no way to determine the size of a block of text unless it is only one line or has line-breaks in it or you know its width. In fact, to use this example, you need to specify the width of the radiobuttons, so it defines a width so we can calculate the height.
Here is a Flex 3 version:
Download Source
Run Example
Comments
Hi, Alex:
How can I use the button you offer? I have tried to do in the Application :
It does not work.
Thanks
-------------------
You have to give it an numeric width like width="100" otherwise it won't know how to wordwrap correctly. I explained why this is required in the blog post
Posted by: jeff | April 10, 2007 01:28 PM
Works like a charm! I've been looking for something like this for a while now. Thanks!
Posted by: Brandon | April 12, 2007 10:20 AM
Hi Alex... thanks for responding to my flexcoders post on this. I've tried your code and it works great. I have just one tweak request... How can I get the radio button vertically aligned to the top of the wrapped text? Right now it appears in the middle. Thanks again for all you do for the Flex community!
----------------
I would override updateDisplayList, call super.updateDisplayList, then get the current icon via getCurrentIcon() and set its y value to where you want it.
Posted by: Merritt | April 13, 2007 09:39 AM
Worked like a charm, thanks.
Here's the fix for the radio button alignment.
override protected function updateDisplayList(unscaledWidth:Number,unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth,unscaledHeight);
this.getCurrentIcon().y = 2;
}
Posted by: Rich | May 10, 2007 03:33 PM
I'm new to this Flex stuff and was wondering how do I use the two files you have in my project?
Thanks
jason
----------------
Ask that question on flexcoders, you'll get better help on how to do that. I generally don't use FlexBuilder for my work.
Posted by: Jason | August 23, 2007 08:28 AM
You say you don't use Flex Builder. What do you use?
-------------
ANT or UNIX shell scripts.
Posted by: Randy Martin | September 30, 2007 10:49 AM
Thanks so much for Alex good example! :-)
Posted by: Jack | November 6, 2007 11:55 PM
I'm getting the following error in the MultilineRadioButton.as file at addChild(textField):
1067:Implicit coercion of a value of type mx.core:IUITextField to an unrelated type flash.display:DisplayObject
How can I fix this?
Posted by: JRosamond | January 30, 2008 12:47 PM
Great! I was building one of these myself but it didn't quite work.
I used this for the Button class and one thing I noticed is that the multi-line text wasn't vertically centred properly until you rolled over the button.
You need to force the button to re-render itself after it's created. I added the following function to my MultilineButton class:
public function forceUpdate():void{
this.updateDisplayList(this.width,this.height);
}
I call this from the tag like so:
And here's the handler that should be in the Script tags:
private function forceUpdateHandler(event:Event):void{
event.target.forceUpdate();
}
Posted by: nicemandan | January 31, 2008 03:06 PM
I'm getting the same error in the MultilineRadioButton.as file at addChild(textField), like Jack :
1067:Implicit coercion of a value of type mx.core:IUITextField to an unrelated type flash.display:DisplayObject
Can anybody help? i'm using Flex 3 Beta 3 Builder.
Thx,
Toni
-----------------------
You'll have to cast it via DisplayObject(textField). These examples were for Flex 2.0.1 and some will need updating for Flex 3
Posted by: Toni | February 6, 2008 03:32 AM
Thanks! I was having this same exact problem, but with regular Button components. I subclassed Button and used the same code as in your MultilineRadioButton class.
Now the "#13;" escape sequence works and my buttons allow multiline labels.
Posted by: Ken | February 28, 2008 12:09 PM
Thank you very much! I just used your code for CheckBox components and it works perfectly.
Posted by: David | March 29, 2008 12:10 PM
Nice blog -- I really need this for a multiline Button! I extended the Button class and adapted the createChildren function slightly for Flex3. Works just fine. I just use \n in the label like label="{'This\nis\nGreat'}"
override protected function createChildren():void{
if (!textField){
textField = IUITextField(createInFontContext(UITextField_NoTruncation));
textField.styleName = this;
addChild(DisplayObject(textField));
}
super.createChildren();
textField.wordWrap = true;
textField.multiline = true;
}
Posted by: Warren Koch | April 7, 2008 06:04 PM
"this.getCurrentIcon().y = 2;" worked in flex 2, but in Flex 3, the icon is pretty well hidden by the internal keyword. Is there any way around this?
-------------
Alex responds:
getCurrentIcon is still mx_internal so
import mx.core.mx_internal;
use namespace mx_internal
should still do the trick.
Posted by: Peter Gardner | April 29, 2008 05:32 PM
I used you code to extend a Button, and published these class (if you dont mind).
I made a link for this post on the blog and also on the code.
Really usefull, thanks.
Posted by: Gabriela Trindade Perry | July 15, 2008 01:10 PM
Does anyone have a working example I could look at? I am trying to create a multi-line label for a button in Flex2.
--------------------
Alex responds:
Several people have used the source and were successful. If you are having problems, pose the question on FlexCoders
Posted by: Ken Greenwood | August 2, 2008 11:24 AM
this is not a problem now
http://flexlib.googlecode.com/svn/trunk/docs/flexlib/controls/CanvasButton.html
Very simple
Posted by: Umer | August 18, 2008 11:14 PM
Hi
I used this component and the text was cut by the verticalScroll for long texts and having fixed width...
This may help in MultineRadioButton.as
textField.width = w - 5;
Thanks
Posted by: Krishnendra | August 19, 2008 04:10 AM
I'd like to use this code as part of an open-source Flex library I've written. Is it something you're willing to release?
---------------
Alex responds:
Yes, as long as I'm free of all liability.
Posted by: Mark | August 25, 2008 07:37 AM