tags:

views:

44

answers:

1

I have a custom component that is basically a VBox with a Label and a TextField.

<mx:VBox width="50%">
    <mx:Label width="100%"/>
    <mx:TextField width="100%"/>
</mx:VBox>

What I want, basically, is to have two of these VBoxes layed out on a HBox and each would take exactly 50% - their children Label and TextField should just obey that.

If I set both Label and TextField's width to 100%, and the Label text doesn't fit, the default behaviour is to expands the VBox width - I don't want that to happen. The TextField should always take 100% of the width, and I'd want the Label to be explicitly set to the width of the TextField, so the text would be truncated and not expand the VBox width.

Is there a way to tell the Label to just obey the VBox (or TextField) width and not be included in the measurement of the VBox width?

Not sure if I was clear. :) Thanks in advance.

A: 

Hi, it wasn't that easy as I thought. At the beginning I wanted to suggest maxWidth but it doesn't work correctly with label. However I just tested this:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"&gt;
 <mx:Script>
  <![CDATA[
   import mx.controls.TextInput;
   import mx.controls.Label;
   private function onTextChanged(event:Event):void {
    var currentText:String = TextInput(event.target).text;
    var shortened:Boolean = false;
    // adding 30 to leave some space for ...
    while ( lbl.measureText(currentText).width > (lbl.width-30) ) {
     currentText = currentText.substr(0,currentText.length-1);
     shortened = true;
    }
    lbl.text = currentText + ((shortened) ? "..." : "" );
   }
  ]]>
 </mx:Script>
 <mx:VBox width="50%">
  <mx:Label id="lbl" width="100%" />
  <mx:TextInput width="100%" change="onTextChanged(event);" />
 </mx:VBox>
</mx:WindowedApplication>

It probably isn't written in a way (just attributed) you expected but it does what you need. If this isn't a solution you could think of extending the Label in the following manner. Crete custom Label:

radekg/MyLabel.as

package radekg {
 import mx.controls.Label;

 public class MyLabel extends Label {
  public function MyLabel() {
   super();
  }

  private var _myText:String;

  override public function get text():String {
   return _myText;
  }

  override public function set text(value:String):void {
   if ( value != null && initialized ) {
    // store the copy so the getter returns original text
    _myText = value;
    // shorten:
    var shortened:Boolean = false;
    while ( measureText(value).width > (width-30) ) {
     value = value.substr(0,value.length-1);
     shortened = true;
    }
    super.text = value + ((shortened) ? "..." : "");
   }
  }
 }
}

And use it like that:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
 xmlns:controls="radekg.*">
 <mx:VBox width="50%">
  <controls:MyLabel width="100%" id="lbl" text="{ti.text}" />
  <mx:TextInput width="100%" id="ti" />
  <mx:Button label="Display label text" click="mx.controls.Alert.show(lbl.text)" />
 </mx:VBox>
</mx:WindowedApplication>

This can be used simply with binding. Once you type very long text into the text input and the Label displays ... click on the button. You'll notice that text() getter returns original text.

Hope this helps.

radekg