21

I'm trying to calculate how WIDE to make my button, based on the text that it will contain, and when I try to google for how to calcuate something as simplistic as the WIDTH OF SOME TEXT, I go cross-eyed just trying to wade through apparently nonsensical esoteric counter-intuitive voodoo. Can anyone out there help simplify for me how I would write a function like this:

public function HowWideWouldThisTextBeIfItWereInThisButton(Text:String,Container:Button):int {
 ...
}

Thanks in advance.

Joshua
  • 6,643
  • 15
  • 55
  • 76
  • When you say the text in the button ... do you mean the label for the button? or a Text Field or a Text Box ? – phwd May 26 '10 at 21:35

8 Answers8

21

So long as you're in a UIComponent, you can use the measureText function.

public function howWideWouldThisTextBeIfItWereInThisButton(text:String,container:Button):int {
   var lineMetrics:TextLineMetrics = container.measureText(text);
   return lineMetrics.width;      
}

That being said, the flex button component should automatically size to the width of the text, if you don't set a width on it. That way if you need the text width, you can just call use the textWidth property.

quoo
  • 6,237
  • 1
  • 19
  • 36
  • 2
    I'm probably doing something wrong, but I get: TypeError: Error #2007: Parameter antiAliasType must be non-null. – Joshua May 26 '10 at 21:59
  • Are you setting antiAliasType? – quoo May 26 '10 at 22:08
  • WHAT antiAliasType? What is that? Where do I set it? Is it a part of lineMetrics? The Button?? How do I find it? – Joshua May 26 '10 at 22:16
  • 1
    What line number are you getting it on? The debugger should tell you what it's a property of - it's likely the button label's, but it's hard to tell w/o seeing the code. It should be set by default though to 'normal'. – quoo May 27 '10 at 13:54
  • 7
    I found an explanation for that antiAliasType oddity [here](http://goo.gl/s1l9C) : "If you are attempting to use the measureText() method, be forewarned that the text you are attempting to measure (text:String) must be within a UIComponent that is ADDED TO THE STAGE (Application) before you attempt to run the method, otherwise you will get the extremely cryptic error of: TypeError: Error #2007: Parameter antiAliasType must be non-null." --- Credit goes to Sunil_Bhaskaran – Russ Jun 08 '11 at 04:52
  • 1
    also, for using it with a `TextField`, you can drop the `text` and use `getLineMetrics` instead, as seem in one example on the [adobe docs](http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/text/TextLineMetrics.html). I'll add another answer just to illustrate this. – cregox Jun 18 '11 at 06:39
  • Do you consider the font size, if I set label.setStyle("fontSize", 16); – sam sha Apr 25 '12 at 04:19
  • Yes, measureText takes font styles into account. – quoo Apr 30 '12 at 15:36
9

This works any format, size, font type. Don't forget properties "autoSize" and "wordWrap"!

var tf:TextField = new TextField();
addChild(tf);
tf.autoSize = TextFieldAutoSize.LEFT;
tf.wordWrap = false;
tf.text = "Whatever here";
tf.width = tf.textWidth + 4; // add 2 pixels-gutters left & right

Your button will need to be "tf.width" wide...

Simmoniz
  • 1,080
  • 15
  • 27
2

Here's how you do it in Spark:

I've modified - simplified - his example a bit here:

var textMetrics:TextLineMetrics = label.measureText( label.text );  
var textWidth:int = textMetrics.width; 
1

Here's a way that works also:

var tempText:Text = new Text();
tempText.regenerateStyleCache(false);
var textWidth:int = tempText.measureText(*yourstring*).width;
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Bly
  • 11
  • 1
1

as I think, textField.textWidth construction works fine... until you change the font size. It seems it calculates width based on 12px font. So, if you have embedded font and global styling you can try fast solution:

var realWidth = myLabel.textField.textWidth * (fontSize / 12);

I've tried this on long and short strings and the result is correct.

guerda
  • 23,388
  • 27
  • 97
  • 146
effrit
  • 11
  • 1
0

Joshua, it really helps to be clear. Are you talking TextField, MX Label, Spark Label, RichText, etc? Different text components use different text engines, such as FTE and TLF and may have different solutions. I certainly wish Adobe had a good set of utilities or sample code which could predict what the size of font rendered onto the controls would be, before you actually do it. But, the good news is that in certain cases - like, a good old fashioned TextField, you can predict this pretty well. You just make a TextField, set it's textFormat field, auto size method and the text. You should be able to get it's size before adding it anywhere. I don't remember what the order was, but, I remember the order you set those properties matters. If you can't figure out how to do it, I can provide a code example. Now, for the new, "improved", components such as Spark Labels - I'll be buggered if I can find a damn way... spent a number of hours on this and haven't found a way.. or someone who knows a way :P.

0

Following up my comment on quoo's answer, here's the code for same purpose, but just grabbing the width out of a TextField, using TextLineMetrics as well:

    public function mtxtWidth(container:TextField):int {
       var lineMetrics:TextLineMetrics = container.getLineMetrics(0);
       return lineMetrics.width;      
    }
cregox
  • 17,674
  • 15
  • 85
  • 116
-1

Sounds like you could use textWidth

Lars Blåsjö
  • 6,118
  • 2
  • 19
  • 23
  • How does this take into consideration the format, font, size and other attributes of the button label? – Joshua May 26 '10 at 21:50