Ultrashock Tutorials > Flash MX 2004 > Developing Components in Flash 2004  
 
by Chafic Kazoun, Rewindlife.com
Download Source Files (44KB)  
 
Developing Components in Flash 2004
 
- discuss this tutorial -

Developing Components in Flash 2004

Component development in Flash has come a long way. In the previous version of Flash MX, Macromedia introduced version 1 of the Macromedia Component Architecture. With Flash MX 2004, Macromedia further improved components. This article explains the various steps required to build a simple component for Flash MX 2004.

Key Changes in Component Development

For component developers with previous experience in Flash MX, here is a summary of the key changes when developing components for Flash MX 2004. These will be covered in more detail later in the article.

New Architecture

Flash MX 2004 contains a new architecture dubbed version 2 of the Macromedia Component Architecture. This framework contains a lot of functionality that you will want to get accustomed to. A v1 component built to Macromedia specifications inherited from FUIComponent. A v2 component, on the other hand, extends either UIObject or UIComponent. Version 2 components have new event, style, focus management, and tab-management systems. UIComponent is almost identical to UIObject with the addition of Focus management and Tab Management (UIComponent inherits from UIObject). Just as in the v1 component framework, you don't have to make v2 components using the Macromedia base classes but you should try and learn the architecture if you want to use such readily-available functionality such as events and styles and focus and tab control. To make this easier, the source code for most of the components is provided in the First Run\Classes\mx directory under your Flash installation directory. On my machine, the complete path to this C:\Program Files\Macromedia\Flash MX 2004\en\First Run\Classes\mx , but this could be different on yours depending on which drive you installed it on and what platform you're running Flash under.


Simple Live-Preview

In MX we used to have to create a live-preview swf for each component. Many people opted not to create live previews as it took extra programming effort to make sure that live-preview always reflected the latest representation of the component. In 2004, Macromedia has made this much easier by allowing you to compile your component into an SWC or Compiled Clip which automatically contains a live-preview.

Metadata Tag Attributes

Metadata Tag attributes allow you to instruct the IDE and compiler of certain parameters and capabilities that your component possesses. One example is the ability to specify the component parameters with your component's class rather than having to specify the parameters in the Component Parameters dialog box. The IDE will automatically update the parameters once you specify the appropriate class for the component.

Note: The IDE does not constantly check for changes to the component parameters. To force the IDE to update the component's parameters, you can open the Component Properties dialog box for the component you would like to update and click on OK . This will force the IDE to parse through the class and update any needed Meta Tags.

ActionScript 2; #initclip and #endinitclip

In MX you had to have all your code embedded inside your Flash application in an #initclip…#endinitclip block. That now is no longer needed. Instead, you write your code in AS2 in an external class file and specify the component's class in the Linkage Properties and Component Properties dialog boxes. You must make sure the class value in both is correct at all times as both are required and serve different purposes with component. The Linkage Properties will associate the movie clip with a class wherein the Component Properties dialog box will ensure your component's Metadata Tags are appropriately set. It is easy to forget when making changes to a component to update the value in both places.

Building your own Flash MX 2004 Component: Overview

It's important to have some idea about what a component is before going through the steps involved in creating one. Briefly, components are just sophisticated movie clips which we package up so they can be reused and distributed. This article assumes that you have some ActionScript 2.0 knowledge (if you don't, you can read Dave Yang's tutorial on ActionScript 2.0), a text editor (or Flash MX 2004 Professional) for writing code and some familiarity in the use of components (I say this because it's hard to build a component if you don't know how the component will be used). If you haven't used components before, you can read Aral Balkan's tutorial on Introducing Flash MX 2004 Components, wherein you will get up to speed with using the latest components.


Step 1: Planning

In the planning phase you should decide what your component will do and write out a specifications document. The specifications document should include the goal of the component, its behavior, and API. If you would like to go further, you can also develop a UML diagram detailing the component's architecture. If you expect to use your component only once, you probably don't need to do a lot of planning.

In this article we will be building a TextBox component. This component will be a simple box with text in the middle. The user should be able to resize the component, set the text, and the background color. You can see an instance of the finished component, below.

TextBox Requirements:

  1. A text property that determines the text displayed and centered in the component. The user should be able to set this property's value through the component inspector and through code.
  2. The component will have a default background color, but should also be able to read the style value specified by the user.
  3. The component should re-size itself appropriately and draw/redraw itself.

Setting up your component

It is always a good idea to develop a component in isolation in its own FLA. This allows you to focus on the component, develop it, and test it out comprehensively without being affected by the idiosyncrasies of the application it will first be used in.

  1. Create a new FLA and save it in a folder called TextBox Component . This will be the FLA of the component you will be creating.


  2. Open the standardComponent.fla file from C:\Program Files\Macromedia\Flash MX 2004\en\First Run\ComponentFLA (The actual location of this file will vary depending on the directory you installed Flash in on your computer and your operating system.)


  3. Open the libraries of both files (Window -> Library ; Ctrl-L)


  4. Locate the UIComponent symbol located in the Flash UI Components 2/Base Classes/FUIObject Subclasses/ folder in the library of standardComponent.fla and drag it to the library of your component FLA. The UIComponent symbol should be copied along with all of the assets UIComponent requires.


  5. Notice that when the symbols were copied, some symbols were not placed in the same location they were in the original FLA. To remedy this, create a folder named FUIObject Subclasses in the Base Classes folder and move the UIComponent , UIComponentExtensions , and FUIComponent Subclasses in there.


  6. You may now close StandardComponents.fla as there is no longer a need for it.
  7. Your component FLA's library now contains the assets that your component requires. UIComponent is the class our component will inherit from. I will not be discussing the capabilities of the UIComponent class in detail, but highly recommend studying it and UIObject which is the class UIComponent inherits from (both are located in the mx.core namespace of the Flash MX 2004 classes).

    At this point, you may be wondering why our component inherits from UIComponent and not the generic MovieClip class. Although you could build your component without using the UIComponent class, you will quickly find that there are many features (events, styles, etc.) that you will need and have to implement yourself. Rather than doing all that, by inheriting from UIComponent, you can easily take advantage of all the hard work and features that Macromedia's engineers put into the component architecture. Additionally, it's important when developing components to make sure to re-use base classes from Macromedia's components. Doing so will ensure that your components will contribute less towards file size when included in Flash applications with other v2 components.

  8. With the necessary groundwork in place, you will need to create the symbol for your component.

    Start off by creating a new, empty MovieClip with a name of TextBox , a linkage identifier of com.rewindlife.controls.TextBox , a fully-qualified class of com.rewindlife.controls.TextBox and make sure the component is being exported for ActionScript but not in the first frame.



    Note: You may notice that we provided an identifier that looks like a fully-qualified class reference. This is not the method that Macromedia employs with its UIComponents that ship with Flash. The Macromedia components instead use the class name alone as the identifier. There is nothing wrong with either approach, but for the instances when you create a component that provides the same functionality, you will find there will be issues with collision of symbol identifiers. One easy way around this is to fully-qualify a class name instead. If you were to set up this component using the methods employed by Macromedia, your component's identifier would be TextBox instead of com.rewindlife.controls.TextBox .

  9. Next, you will need to specify the settings for the Component Definition Dialog Box.

    Open the Component Definition Dialog Box by right-clicking on your symbol in the library and selecting Component Definition.

  10. All that is required of you at this dialogue is to specify the AS 2.0 Class for the component. This is the same as the MovieClip's class that we specified above ( com.rewindlife.controls.TextBox ). You may be wondering why we haven't specified any of the parameters at this point. In Flash MX 2004, Macromedia has added Metadata tags that you can include directly in the ActionScript 2 Class file. This, as we will see later, is a more convenient way of setting up component parameters. It is also the recommended way in Flash MX 2004.

  11. After adding your component to the library, double click the component in the library to reveal the timeline. Use the screenshot below as a guide when creating the timeline structure described in the next few steps.

  12. Create a new layer and call it Actions .

  13. On Frame 1 of the Actions layer, type in a stop(); action using the Actions panel. This will ensure the playhead we never get to the 2nd frame of our Component.

  14. Create a new layer and call it Bounding Box. Place an instance of the Bounding Box MovieClip from the library onto that layer.You may not have noticed earlier, but by copying over the required assets, you also copied over the default bounding box that Macromedia provides. The bounding box is located in the library under Flash UI Component 2/Component Assets . The bounding box (also referred to as “dead preview”) is used by the IDE to give the component an initial presence when placed on the stage. It is also used to give a visual representation of the component when a user has disabled live-preview in the authoring environment. In this example, we will be using the default bounding box provided by Macromedia; a simple white box with a black border. For a component that is developed for limited usage, using the default white box is a good idea. For a component developed for a wide audience, it is always good to keep in mind that many users disable Live Preview in the authoring environment. Having a simple white box may not represent the component adequately. In such cases, providing a static graphical representation of the default state of the component would be better.

  15. Give the bounding box instance an instance name of boundingBox_mc and ensure that its registration point is (0,0). You can set the registration point by setting its x and y values to zero using the Property Inspector.

  16. Create a layer for your component's assets called Assets and create a keyframe on the second frame of this layer ( Insert->Timeline->Keyframe ; F6).

  17. Drag the UIComponent symbol onto the second frame of the Assets layer. All of the component's assets are placed on Frame 2 because they never need to be instantiated (and they never are, because of our stop() action on Frame 1). However, adding them to the timeline is crucial to ensure that they are included in the component and packaged correctly when it is exported. Also, if you have developed components in Flash MX, you may have noticed this is done differently. The reason is that in Flash MX, many of the components has an issue where all it's code was compiled onto the first frame of a Flash movie. With this setup, components will no longer have that issue. For this particular component, you only need to place an instance of UIComponent on stage, but sometimes you may need to place other assets.

The structure of your components is now ready and you now need to write some code. If you have gotten this far and would like to verify what you have done so far, open the file named TextBoxSetup.fla and compare it with your FLA. They should be identical.

ActionScript 2.0

Flash MX 2004 has introduced a new version of ActionScript called ActionScript 2.0 and this is the language used for creating v2 components. This article does not go into detail on AS2 but you can find a good overview of ActionScript 2.0 in Dave Yang's excellent tutorial.

The Code

Below is the code for our component. Rather than go through and explain everything with references to the code, I have provided comments within the code. It is important to note that this component inherits from (extends) UIComponent. Because of this, there will be some method calls that you may not recognize. Had you built this component as a subclass of MovieClip, you would not have been able to use all the additional features provided by Macromedia's architecture. A full explanation of the framework is beyond the scope of this article.

/**
A TexBox component
@class TextBox
@package com.rewindlife.controls
@author Chafic Kazoun
*/
import mx.core.UIComponent;

// We declare our class fully qualified. Also we
// make this class a child of the UIComponent class
// by using the extends keyword
class com.rewindlife.controls.TextBox extends UIComponent
{ // These are required for createClassObject()
static var symbolName:String = "com.rewindlife.controls.TextBox"; static var symbolOwner:Object = com.rewindlife.controls.TextBox;
// we declare our Bounding Box here so that we can
// reference it in our code
private var boundingBox_mc:MovieClip;
// this will be our TextField that we will use to display the text
private var textBoxLabel:TextField = null;
// this will serve as our default background color
private var defaultBgColor:Number = 0xFFFF33;
private var _text:String = null;
private var depth:Number = 0;
// This is our constructor. Most of the time you will
// just leave this blank when developing UIComponents.
// Instead we use the init() function to set up our component
function TextBox(){}; // This function is automatically called when our component
// extends the UIComponent class.
private function init():Void
{
// we call the superclass' init function which is required
// when subclassing UIComponent
super.init();
// Since we have a bounding box, we need to hide it and make sure
// that its width and height are set to 0. Notice that we are not using
// "this" as we used to in AS1. In AS2 the compiler automatically
// references the class members.
boundingBox_mc._visible = false;
boundingBox_mc._width = boundingBox_mc._height = 0;
}
// This function is also called automatically when our component
// extends the UIComponent class.
private function createChildren():Void
{
// This method is useful for when you want to create attach sub-objects.
// This method only gets called once.
// In our component
// the only child object we need to create is the TextField. The rest
// is handled by the draw function as we will see below.

// createLabel() is a method provided by UIObject that we can use
// when we want to create a TextField. This is recommended
// over the use of createTextField() method we are accustomed to. textBoxLabel = createLabel("textBoxLabel",depth++);
};
// This function is called every time our component is invalidated.
private function draw():Void
{
// We get the appropriate background color from the style manager
// the getStyle() method is provided to us by the framework. Make
// sure to review the list of styles that the Macromedia components
// support from the help as you will want your component to use the same
// styleNames.
if(getStyle("backgroundColor") == undefined)
{
var bgColor:Number = defaultBgColor;
}
else
{
var bgColor:Number = getStyle("backgroundColor");
}
// We draw our box first
beginFill(bgColor);
// This is a method provided to us by UIObject to draw rectangles
drawRect(0,0,width,height);
endFill();
// We set the Label's text property to the value
// of the text the user has set using
// the getters and setters.
textBoxLabel.text = text;
// We set the size of the Label so that it is viewable
textBoxLabel.setSize(textBoxLabel.textWidth+3,textBoxLabel.textHeight+3);
// now we center our Label in the middle of our box
var cWidth:Number = width/2 - textBoxLabel.width/2;
var cHeight:Number = height/2 - textBoxLabel.height/2;
textBoxLabel.move(cWidth,cHeight);
}
// The size function is automatically called whenever our component is
// resized.
private function size():Void
{
// Since we don't have any special implementation
// for sizing. We can just invalidate the component
// invalidating the component will cause the component's
// draw() function to be called.
invalidate();
};
// This is our setter for the text property.
// This will set the value and invalidate() the component
// by adding the [Inspectable] meta-tag, the Flash IDE will
// add an available text property to the property inspector
[Inspectable]
function set text(newText:String):Void
{
_text = newText;
invalidate(); };
// This is a getter for the text property. Our user can
// use this property to retrieve the current value of the text
function get text():String
{
return _text;
} };



Explanation of the Code

Believe it or not, that is all the code that is required for the component. That said, there are some important concepts we covered that should be discussed in a bit more depth at this point. The code is well commented, but you might be wondering how some things work.

First off, this code must be placed in a file called TextBox.as in the com.rewindlife.controls.TextBox namespace. In ActionScript 2.0, folders are translated into namespaces, so all you need to do is create a folder structure com\rewindlife\controls in the same folder where your FLA is located and save your class file there. Alternatively, you could create a file with a filename of com.rewindlife.controls.TextBox.as and place it in the same folder as the fla if a component will only have a single class.

Bounding Box Handling

If you recall, you had previously placed a bounding box in your component symbol. The bounding box is used to give the component a representation when a user turns live-preview on in the IDE. It is also used to set the bounding when a user is re-sizing your component in the authoring environment. Since the bounding box is not part of your rendered component, can hide it and set its width and height to zero. In this example, you used a white box with a black border as the bounding box. It is a good idea to provide a more useful dead preview by actually having a static representation of the component rather than just a white box.

Static variables symbolOwner & symbolName

You probably noticed two static variables and may not have been sure what the purpose of these two variables is. These two variables are used by the framework to allow the createClassObject() method to function correctly. symbolName should be set to the linkage identifier of our component, and symbolOwner should be set to the class itself. When a user calls the createClassObject() function, the appropriate symbol for the class specified is retrieved and the correct MovieClip is attached.

Inheriting from UIComponent

If a class inherits from UIObject or UIComponent , certain functions are called when the component is instantiated, when the component is re-sized, or when the component needs to be redrawn. When a component is initializing, the init() , createChildren() , and draw() functions are called in that order. The init() , and createChildren() methods are never called after initialization.

The draw() function is called every time the component needs to be redrawn. You should never call the draw function explicitly, you must either call invalidate() or redraw() . The reason you should not call draw() yourself is that in some cases, your component may have multiple redraw() calls in a single frame. When you call invalidate() , the component will queue all the requests and execute them in the next frame.

Handling Resizing

Whenever a component is resized, the size() function is called by the framework. In your component, you just call invalidate() within this function which will redraw the whole component (call the draw() function) to the new size. If this were a more sophisticated component, you may split up the sizing code from the drawing code to improve performance.

Metadata Tags

You probably noticed the line [Inspectable] preceding the property text setter. This is a meta-tag that we include to instruct the IDE that there is a property of text that is available for the user to set. That is all that is needed to add a property to the IDE's component inspector. In this example we used one of the simplest of meta-tags. Meta-tags can contain more details on the property that is available. Also meta-tags can be used to specify other information about our component. The Flash MX 2004 help-files detail all available meta-tags. The IDE will not automatically update without you telling it to re-processing your class file. To do this, open the Components dialog and select OK , and your component's definition should be updated.

Live Preview

Live Preview allows you to see how the changes you make to a component's parameters will affect its final appearance when the movie is tested, all from within the authoring environment, without having to test the movie. In Flash MX 2004, Macromedia has made the process of creating a live preview very simple. All you do is either convert your component to a compiled clip, or export the component as an SWC, and a Live Preview automatically available. In both cases, what is happening is the IDE is compiling the component so it can be executed at authoring time. The difference between a compiled clip and an SWC is very subtle. An SWC is a packaged up version of the component that can be distributed. A compiled clip is not transferable from one FLA to another. It is meant to reside in a single FLA. For our purposes, you can at this point convert the component to a compiled clip by right-clicking on the component in the library and selecting convert to compiled clip. Once that is done, you should see a new symbol appear in the library. This symbol is the compiled version of your component. There are other benefits of converting a Component to a compiled clip, since a compiled clip's code is already compiled, compiling a movie that contains that component will take less time. If a movie contains many uncompiled components, it will benefit greatly from having its components converted to a compiled clip.

Testing out your Component

To test out your component, all you need to do is drag an instance of the component onto the stage, resize it and change any of the values of the properties. As a simple test, you may change the text property of the TextBox component to Hello World , and your component should reflect that change within the authoring environment. Once you are ready, test the movie (Control->Test Movie ; Ctrl-Enter) to make sure that the component initializes correctly. Many times, you will need to perform in-depth testing of your components to uncover and fix runtime issues. Unit testing your components is one way to make sure that they work exactly as required.

Distribution

To distribute your component, you must export it as an SWC. Developers can then place the SWC file in their components folder to have it show up in the Components panel. An SWC is really just a zip archive containing all the needed data for the component to function. To export a component, right-click the component symbol in the Library and select Export SWC File . Alternatively, you may distribute an MXP. An MXP is a packaged up extension file that can be installed using Macromedia's extension manager. Using an MXP is preferred over distributing SWCs as it allows for an easier installation process and allows you to include documentation that will be installed along with the component. We will not be covering the details of an MXP in this article, but further information on MXPs can be found by reviewing the MXI file format at http://www.macromedia.com/go/em_file_format .

Conclusion

In this tutorial, you learned the basics of creating a component using version 2 of the Macromedia Component Architecture. Granted, the component is a simple one but it has hopefully helped you to understand the component development process.

- discuss this tutorial -
 
©2003 Ultrashock.com - All rights reserved