Seidleroni
Seidleroni

Reputation: 1044

Adobe Flex - any way to automatically change font size to fit in its container?

I have a component in Flex, and part of that component is a label. Is there a way to automatically adjust the font size to fit into its container?

Upvotes: 1

Views: 2379

Answers (2)

Viktor Grekov
Viktor Grekov

Reputation: 1395

If you mean a single-line label then this is the component that may help you. Consider that it can only make it's font size smaller (as a reaction to container's width reduction).

import flash.events.Event;
import flash.text.TextLineMetrics;

import mx.controls.Label;
import mx.events.FlexEvent;

public class ElasticLabel extends Label {
    private static const EXTRA_SPACE:Number = 2;

    private static const MIN_FONT_SIZE:Number = 6;

    private var fontResizeRequired:Boolean = false;

    public function ElasticLabel() {
        super();

        addEventListener("explicitMaxWidthChanged", triggerFontResize);
        addEventListener(FlexEvent.VALUE_COMMIT, triggerFontResize);
    }

    private function triggerFontResize(event:Event):void {
        fontResizeRequired = true;
    }

    private function get currentWidth():Number {
        var textMetrics:TextLineMetrics = measureText(text);
        var textWidth:Number = textMetrics.width;
        var paddings:Number = 0;
        var paddingLeft:Number = getStyle("paddingLeft");
        if (!isNaN(paddingLeft)) paddings += paddingLeft;
        var paddingRight:Number = getStyle("paddingRight");
        if (!isNaN(paddingRight)) paddings += paddingRight;
        return textWidth + paddings + EXTRA_SPACE;
    }

    private function resizeFont():void {
        if (!isNaN(maxWidth) && maxWidth > 0) {
            var fontSize:Number = getStyle("fontSize") as Number;
            while (maxWidth < currentWidth 
                    && fontSize > MIN_FONT_SIZE) {
                fontSize -= 0.5;
                setStyle("fontSize", fontSize);
            }
        }
    }

    override protected function updateDisplayList(unscaledWidth:Number, 
            unscaledHeight:Number):void {
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        if (fontResizeRequired) {
            resizeFont();
            fontResizeRequired = false;
        }
    }
}

Upvotes: 0

Christian Nunciato
Christian Nunciato

Reputation: 10409

Not automatically (at least not that I know of), without setting up some sort of event handler, and taking action on the occurrence of some event. Here's a simple AIR app that demonstrates one approach -- in this case, a resize event triggering a change in the fontSize of a Label:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="this_creationComplete()">

    <mx:Script>
        <![CDATA[

            import mx.binding.utils.BindingUtils;
            import mx.binding.utils.ChangeWatcher;

            [Bindable]
            public var myValue:int = 0;

            private function this_creationComplete():void
            {
                setSize();

                addEventListener(Event.RESIZE, handleResize);
            }

            private function handleResize(event:Event):void
            {
                setSize();
            }

            private function setSize():void
            {
                lbl.setStyle("fontSize", this.height / 2);
            }

        ]]>
    </mx:Script>

    <mx:Label id="lbl" text="Hello, world!" />

</mx:WindowedApplication>

Here, when the app gets resized, the label's fontStyle property gets changed to one-half the app's height; scale it up and down and you'll see how it works. There are certainly other approaches, as always, but because we're dealing with styles and not bindable properties, a little custom coding is most likely called for. Hope it helps!

Upvotes: 1

Related Questions