Wrangling Flex Labels: Auto-sizing Text

by

I am currently working on a project where we have a
fixed-width dialog box, and need to fit the title text in a label. The problem
is, the text is too long. What to do? Well, the basic Flex Label provides you a
couple of options: show an ellipsis (…) at the end of the label or cut the text
off. Neither of these solutions was viable.

This is a common problem that occurs in UI development:
fitting text in a limited space. My solution to this was to create a LabelUtil
class that automatically adjusts the font size of the text to fit the width of
the label.

Here is the meat of the code:

import
flash.text.AntiAliasType;

import
flash.text.Font;

import
flash.text.GridFitType;

import
flash.text.TextLineMetrics;

import
mx.controls.Label;

import
mx.core.Application;

import
mx.core.UITextFormat;

import
mx.styles.CSSStyleDeclaration;

import
mx.styles.StyleManager;

      
publicclass LabelUtil
{
      publicfunction LabelUtil()
      {
      }
             
      staticpublicfunction constrainTextToWidth( label : Label, htmlText : String ) : void
       {
             var  style : CSSStyleDeclaration =
StyleManager.getStyleDeclaration(
“.” +
label.styleName);

       var fontSize :
Number = style.getStyle(
“fontSize” ) as Number;
       label.setStyle(
“fontSize”, fontSize );
       label.htmlText
= htmlText;

       label.invalidateSize();
       label.validateNow();

                    
             while (
getTextWidth( label.text, fontSize, style ) > label.width )

             {
                   fontSize =
fontSize – 0.5;

                   label.setStyle(
“fontSize”, fontSize );
             }
      }
             
      staticpublicfunction getTextWidth( text : String, fontSize
: Number, style : CSSStyleDeclaration ) : Number

      {
             var textFormat
: UITextFormat =

             new
UITextFormat(

                   Application.application.systemManager,
                   style.getStyle(
“fontFamily” ),
                   fontSize,
                   null,
                   style.getStyle(
“fontWeight” ) == “bold”,
                   style.getStyle(
“fontStyle” ) == “italic”,
                   null,
                   null,
                   null,
                   null,
                   style.getStyle(
“paddingLeft” ),
                   style.getStyle(
“paddingRight” ),
                   style.getStyle(
“textIndent” ) );
             textFormat.antiAliasType
= flash.text.AntiAliasType.ADVANCED;

             textFormat.gridFitType
= flash.text.GridFitType.PIXEL;

             var textMetrics
: TextLineMetrics = textFormat.measureText( text );

             return
textMetrics.width;                    

       }
}

OK, so what’s going on here? First we pass in the label in
question and the html text to be displayed (note the function will also work
for plain text).  Then, we measure
the width of the text and compare it to the width of the label. If the text is
narrower that the label, we’re done. Otherwise, we reduce the font size by a
half-point until the text width is less than the label width.

There are a couple of things to consider using this method:
First, you must specify the width of your label in pixels (this shouldn’t be a
problem as this solution applies to a fixed width label). Also, you’ll need to
make sure to define a CSS style for the label (you could modify the method to
use the label’s inherent style properties, but I didn’t need to).

Notice that I am using a UITextFormat object to measure the
text width. Why is that, when the label provides a textWidth property? The answer
is that textWidth is unreliable in the label control. This method is rock
solid.

Hope this helps your labeling needs. Happy Coding!

1 Comment

Leave a Reply

Your email address will not be published. Required fields are marked *