ActionScript File Icon

Dynamically modifying a TextField inside the evil SimpleButton class

As of yesterday, I had never used the ActionScript 3 SimpleButton class… and now I wish I nad not ventured anywhere near this ill-devised piece of *&?%. Should you ever want to use it or if you are currently struggling with it, I strongly suggest you read this quick primer.

Maybe it’s my fault. I was expecting a completely different behaviour from this seemingly simple class. It all started with this ordinary scenario : a button on the stage, a text field inside the button and me wanting to dynamically change the text in the text field. Since my text field had an instance name I thought it would be as simple as :

myButton.myTextField.text = 'New text';

Nope. This does not work. Even though Flash let’s you put DisplayObjects inside a SimpleButton instance, things are not as they seem. First of all, the SimpleButton class does not extend DisplayObjectContainer and is not dynamic (contrary to the MovieClip class). Therefore, we should’nt be able to put DisplayObjects into it and give them instance names. But we are ! How come ?

The thing is that each of the 4 frames on the scenario of a SimpleButton object are actually properties of the object itself and not traditional frames. These properties are called upState, downState, overState and hitTestState. This means that my TextField object – which spanned all 4 frames – is actually broken down into 4 different objects. No wonder I have trouble accessing it. What’s particularly annoying is that the Flash IDE will let you enter an instance name on the text field even though it is completely unusable. The debugger even knows about this property although it gives it a value of null.

The documentation is also unclear. It says that upState, downState, overState and hitTestState are DisplayObjects while in fact they can also be DisplayObjectContainers. For instance, if you put a single TextField inside the “Up” frame, the debugger reports the type of the upState property as TextField (which inherits from DisplayObject). However, if you put a TextField + a shape on the “Up” frame, the upState property is now reported as being a Sprite (which inherits from DisplayObjectContainer). Go figure…

So, is it even possible to change the text property of my TextField ? Well, it turns out it is (sort of). If you have a single TextField inside your SimpleButton, you can use this :

(myButton1.upState as TextField).text = "New text";

Obviously, this will only change the “up” state. You would need to do the same for other states as well. If your SimpleButton contains more than one object, you will need to use this :

((myButton2.upState as DisplayObjectContainer).getChildAt(1) as TextField).text = "New text";

You would need to figure out which index to pass to the getChildAt() function to fetch the right object. This, in itself, can also be a pain. Perhaps you now understand why I hate this thing so much… My advice ? Find a nice button component (not so easy) or make your own button by using a MovieClip.

Here is an actual FLA example demonstrating the issue (CS 5.5). Hope this helps.

Comments

  1. Thank you, Jean! This helped me out a lot.

    I’ve been struggling with the getChildAt(number) a lot, last hours untill I visited your website. I couldn’t get the mouseOver right; you explained very well!

    Thanks! Appreciate your work and help. 🙂

Leave a Reply

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