To make it easy for users of our class to change its private properties without actually editing the class file, we employ "setter" functions. These functions are special, and are set apart from other functions through the use of the keyword "set." They're written as public functions, otherwise they wouldn't be of much use. Let's add one to our Expander class. Just insert it in the list of functions, right after the private ones (that is, right after "contractMe"):
public function set startWidth(theValue:Number) {
    _startWidth = theValue;
    initClip();
}

Save the file. Now go back to the fla file again. Change the code there so that it reads:
import com.mysite.effects.Expander;
var expander:Expander = new Expander(help);
expander.startWidth = 40;

Test the movie. Your help box will now start and end with a different value, that being the new one you just gave it. Notice that although "set startWidth" is a method (note also there's a space in the name, which is unusual), and it expects a parameter, from the external code we actually are able to treat it as though it were a property. Rather than calling it with its argument in parentheses, like we normally would, with this kind of method we call it using an equals sign instead, as though we were setting a property.

I can almost hear you asking, "Why don't we just use a public property, then?" The answer is that by doing this, we protect the actual property from being changed improperly by external code. By using a separate setter function, we also introduce another layer of protection. This way, we could also potentially filter the value we get using conditionals, so that we can decide what range of values we will or won't accept. Also, in our present case, it allows us to add in a call to the initClip function so that our value gets updated immediately.

And that's how setters work! I'm going to show you a "getter" function as well, just so you'll know how they work, but "Expander" isn't going to be using any. But if it did, it might look like this:
public function get startWidth():Number {
    return _startWidth;
}

Notice that "setters" always receive an argument as a parameter, and "getters" always have a return value. The same opportunity to run other code and/or filter data exists with getters as well. The same technique of using dot syntax and treating it like a property applies as well.

This simple concept of getters and setters is sometimes difficult for those new to classes to comprehend. I know, because I have been one of them. The reason is that it's one of those things that breaks the ordinary rules. The concept of getters and setters might be thought of as analogous to "castling" in a game of chess: it's one of those things that defy the rules of how the pieces normally move.

In any case, here are the setter functions that you can add to the list of functions in Expander:
public function set startWidth(theValue:Number) {
    _startWidth = theValue;
    initClip();
}
public function set startHeight(theValue:Number) {
    _startHeight = theValue;
    initClip();
}
public function set startAlpha(theValue:Number) {
    _startAlpha = theValue;
    initClip();
}
public function set duration(theValue:Number) {
    _duration = theValue;
}
public function set easing(theValue:Function) {
    _easing = theValue;
}
public function set endWidth(theValue:Number) {
    _endWidth = theValue;
}
public function set endHeight(theValue:Number) {
    _endHeight = theValue;
}
public function set endAlpha(theValue:Number) {
    _endAlpha = theValue;
}

Now, change the code in the fla file to the following (let's set a bunch of values to test our setter functions):
import com.mysite.effects.Expander;
import fl.transitions.easing.*;
var expander:Expander = new Expander(help);
expander.startWidth = 40;
expander.startHeight = 10;
expander.startAlpha = .1;
expander.duration = 6;
expander.easing = Regular.easeOut;
expander.endWidth = 500;
expander.endHeight = 300;
expander.endAlpha = .8;

Note that you have to import the easing classes into the fla file as well. Fla files automatically find the classes in the packages that start with "flash" so that no import is necessary. Not so with the classes resisding in packages under "fl." They must be imported. We had to add that here just so we could send Expander a different easing class to use. Anyway, test the movie. Now the Expander class is fully functional, and customizable from outside the class. Congratulations!

There's just one final loose end: Whenever an instance of our class expands or contracts, it ought to come to the front of Flash's stacking order. That way, if there were more than one instance of Expander on the stage, whichever one you clicked would come to the front. I also told you there was an easier way than the line of code I gave you in the last tutorial. All you really have to do is perform an addChild on the instance (from it's parent). Even though it already is a child, telling the parent to add it as a child again doesn't hurt anything, and has the effect of bringing the clip to the front of anything else on the display list. Add this line to the beginning (make it the first line) of both the expandMe and contractMe functions:
_clip.parent.addChild(_clip);


And that concludes this tutorial. I hope you've enjoyed it, and learned some valuable things. If you did, I hope you'll let me know. Thanks in advance!

Happy coding!

Jody Hall