views:

1145

answers:

3

Is there a workaround for displaying multiline text in Flex 3? The two controls I have tried so far are mx:Text, and mx:TextArea. Each control has its own bug associated with it. For reference: mx:Text bug - http://bugs.adobe.com/jira/browse/SDK-9819 mx:TextArea bug - http://bugs.adobe.com/jira/browse/SDK-12616. Basically, neither control handles scrolling correctly if you do not specify a height and the text wraps onto the next line (height is determined dynamically by Flex, based on the wrapping). Does anybody have a workaround that might be helpful?

Thanks.

Update: One of the methods I have tried in the past has been to manually calculate the height of a mx:Text element. I can do this by using the following:

var textItem:Text = new Text();
var len:int = value.length;
var lines:int = int(len/115) + 1;
var height:int = lines * 20;
textItem.height = height;

While this seems to get around the problem in mx:Text, there is one big fault. The calculation relies heavily on font-size, letter-spacing, and the width of textItem. I can use this method, and move on with my project. However, maintenance on this is inevitable, and with code like this, it will a gigantic PITA.

A: 

I've not actually been able to work with this extensively, but I have run into that problem before. A hackish way to do this is to have a listener for when the text area has finished rendering, when it does, call a setTimeout and then adjust the height accordingly. This is very ugly.

BindingUtils is probably where the answer lies, but I was pulled off of the related project before I could do the appropriate experiments.

Christopher W. Allen-Poole
+2  A: 

I've had to deal with this a few times myself. The best way I've found to get dynamic height sizing of <mx:Text> is to leave the height out of the text and then specify a percent height of 100% on the enclosing VBox, HBox, etc. Something like the following should work for you:

<mx:VBox width="100%" height="100%">
    <mx:Text text="Your really long text goes here." width="100%"/>
</mx:VBox>

As this is a bit of a hack itself, your milage may vary.

Edit

If you want to extend your above example so that maintenance on the code is easier, you should look into the TextLineMetrics class. This will allow you to measure the width and height of your text, taking into account font, size, etc. The docs for TextLineMetrics can be found here. To use your above example, you'd want to do something like the following:

var textItem:Text = new Text();
var metrics:TextLineMetrics = textItem.measureText( value );
var len:int = metrics.width;
var lines:int = int(len/textItem.width) + 1;
var height:int = lines * metrics.height;
textItem.height = height;
Dan
I will try this out, and see how it goes. Thanks.
Rob Lund
The TextLineMetrics object looks like it is going to win out here. I will say that in most of the cases I tried, I needed to add textItem to its parent before creating metrics. Otherwise, I would get an anti-aliasing error.
Rob Lund
A: 

I use a variable height text area class that works very well for me:

package
{
    import mx.controls.TextArea;

    /**
     * TextArea that xpands to the height of the content contained
     * within. 
     * @author joel
     * 
     */ 
    public class VariableHeightTextArea extends TextArea
    {
     public function VariableHeightTextArea()
     {
      super();
     }

     override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number) : void
     {
      super.updateDisplayList(unscaledWidth, unscaledHeight);
      if(this.height != int(this.textField.measuredHeight) + 5 )
      {
       this.height = this.textField.measuredHeight + 5;
      }   
     }
    }
}
Joel Hooks
This does seem like a useful class, however Bug #12616 (linked above) is really what is stopping me from using a TextArea. The way that TextAreas handle scroll events is pretty lame.
Rob Lund