tags:

views:

431

answers:

2

I want to make a label that has a tiny title above it, for example so the label say $1,000 with a small retail price or our price above it. I am trying to add the title label to the display list of the main label. I get no error but the title does not show up. I also considered rawChildren but apparently Label has no rawChildren property.

Here is my code:

package
{
    import mx.controls.Label;

    public class PriceLabel extends StrikeThroughLabel //<-- exntension of label to add strike
    {
     private var _title:Label;

     public function PriceLabel()
     {
      super();
     }

     [Bindable]
     public function set title(s:String):void
     {
      if(_title == null)
      {
       _title = new Label();
       addChild(_title);
       this.alpha = .2;
      }
      _title.text = s;
     }
     public function get title():String
     {
      var s:String
      if(_title != null)
      {
       s = _title.text;
      }
      return s;
     }

    }
}
+1  A: 

Why not create a custom component that contains both labels as its children, instead of trying to throw a child on the Label? That feels cleaner to me, as adding children to build-in components like that doesn't seem right.

Herms
I thought about this, but I like how a Label's size is auto to its own text, not sure how I could make a Canvas like that? Is there a way?
John Isaacks
Sure, just set the size of your Canvas to the size of the Label. There's a callback you need to override when defining your component in order to set the size at the right time, but I can't remember which method it is off the top of my head. The Flex docs should be able to tell you.
Herms
+1  A: 

If you add children to a Flex component that is not a container, then you have to manually manage sizing and positioning of those children. Containers do a lot of that work for you.

Here's what you should do:

  1. Move the creation of your child Label into an override of the createChildren() function.

  2. Set the text property of the child label in an override of the commitProperties() function. Your title getter and setter should save the value in a _title variable to be used later for the assignment in commitProperties(). This is actually important for performance.

  3. Override the measure() function and update measuredWidth and measuredHeight to be the maximum width and height values of the main label and it's child.

  4. Override updateDisplayList() and use setActualSize() on the child Label to set it to the required width and height.

That may seem like a lot of work, but in terms of best practices, that's the way you're supposed to build custom components. The Flex Team at Adobe spent a lot of time maximizing performance, and that's why things happen in several steps like that.

That's how to do it based on what you asked. Personally, I would make a subclass of UIComponent with two Labels or UITextFields as children, each with their own separate property.

By the way, the rawChildren property is only available on containers. It exists so that you can add "chrome" to a container that isn't part of the container's child layout algorithm. For example, Panel has a title bar and a border that aren't affected by the vertical/horizontal/absolute layout options.

joshtynjala
Thank you very much for this in depth answer!
John Isaacks