Accessibility

Exploring the version 2 component architecture in Flash 8

Waleed Anbar

Adobe

Note: This article was originally written about the Macromedia Flash MX 2004 component architecture. The component architecture in Flash 8 is largely unchanged from that of Flash MX 2004.

Version 2 of the Macromedia Flash 8 component architecture offers a robust architecture for building highly usable, visually rich interfaces for the web or for creating custom user interface controls and components. Engineered to give you the best possible experience building rich, interactive web application interfaces using industry-standard controls and components, it introduces a number of enhancements over its predecessor. These improvements are the result of new possibilities made available by the new version of the ActionScript language specification and a wholly re-engineered component architecture.

Macromedia built this new architecture on a robust foundation that raises the ceiling on the possibilities of component and application development. It makes available a number of system-level managers for ensuring that applications built with the architecture perform well, adhere to interface standards, and deliver a high-quality end-user experience.

Here are a few things that are part of the new component architecture:

Some key features of Flash 8 facilitate improvements in the component architecture. This article outlines these enhancements in both the language and architecture.

Requirements

Flash 8 Professional


v2 architecture source code

Find version 2 (v2) architecture source code in the following locations:

You can also find it precompiled, in SWC format, in Flash Professional 8.

Examining the ActionScript 2.0 Language

Version 2 of the Flash 8 component architecture is written entirely in ActionScript 2.0, an enhanced version of the ActionScript language derived from the ECMAScript Edition 4 Netscape Proposal and JavaScript 2.0 Proposal. ActionScript 2.0 allows you to use higher-level language constructs for class and interface definitions; stronger typing of variables; parameters and return values; static, public, and private class members; and other enhancements geared towards a more familiar model for better and faster coding.

Classes, interfaces, packages, and attributes are among some of the long-awaited conceptual enhancements to ActionScript.

Classes and Interfaces

The class and interface keywords abstract much of the low-level details of object inheritance and prototypes. While creating a class in Macromedia Flash MX required modifying its prototype and strange syntax like Object.registerClass(), now the syntax becomes much clearer and more well-known:

class MyClass extends MovieClip {
...
}
          

You now declare members inside the body of the class definition.

You declare interfaces the same way. An interface is a set of methods defined by name, arguments, and return values only—no implementations. An interface is useful for creating a set of classes that have the same methods, while leveraging the compiler's error-checking capabilities. A class implements an interface using the implements keyword:

class MyClass implements Serializable {
...
}
          

Interfaces and class definitions exist only in external ActionScript files and are optionally linked to movie clip symbols in the library of a FLA. Once that linking occurs (using the Linkage options of a movie clip symbol), instances of the symbol are associated with the class and all methods and properties defined by that class are available on the instance. Additionally, the component's properties appear in the Component Parameters panel for easy editing inside Flash.

Find more information about ActionScript 2.0 in the Using Flash guide.

Packages

One of the most time-saving enhancements in ActionScript 2.0 is the package, a means for managing classes in large projects. Packages allow you to group classes into namespaces for both conceptual management and physical management on disk. A package consists of an ActionScript file that defines a class whose name consists of a path plus the class name. The path corresponds to the location of the class file on disk, starting at the root of the class path. The compiler imports any classes you reference in your code, provided it knows where to find the class.

This is where packages come in handy. For example, the ActionScript file defining the Label class exists in mx/controls/Label. Accordingly, you declare the class as follows:

class mx.controls.Label extends UIObject {
...
}
          

In this case, both "mx" and "controls" are namespaces. They exist in the default class path for Flash at the same location as the v2 architecture source code mentioned previously.

You can find all Flash 8 components here. Looking in this folder, you will find the "mx" directory and, nested inside it, "controls." Inside "mx/controls" is the ActionScript file, Label.as, which defines the class.

Compile the Label class along with your project using this line of code:

import mx.controls.Label;

This won't make a Label appear on the Stage or in the SWF because you didn't include any Label graphic elements in the library. To do so, drag the Label from the Components panel onto the Stage.

Find more information about packages and how to use them in the Using Flash guide.

Attributes

Use attributes to specify metadata that the authoring tool uses to do the following:

Here are the most common attributes:

Here's an example of a bindable, inspectable property. It's excerpted from the Label component (mx.controls.Label):

[Inspectable(defaultValue="Label")]
[Bindable("writeonly")]
function get text():String
{
     return getText();
}
function set text(t:String):Void
{
     setText(t);
}
          

Find more information about attributes and using them in your components in Allen Ellison and Nigel Pegg's article, Building and Testing Components in Macromedia Flash MX 2004.

Examining the Component Architecture

Version 2 of the Flash 8 family of components provides a foundation for growth and expansion as users and Macromedia build onto it. Its hierarchy of classes (see Figure 1) comprise the UI components—which most Flash users are familiar with from the Components panel—and a number of other singleton classes, smaller hierarchies, and other resources that exist as various managers and mix-ins (see the section "Using Managers and Mix-ins") to provide system-level application services or to assist in component development.

Hierarchy of classes in Version 2 of the Flash 8 component architecture

Figure 1. Hierarchy of classes in Version 2 of the Flash 8 component architecture (click to open full-sized diagram)

This hierarchy is made possible because of inheritance—the concept by which a class inherits the methods and properties of another class by subclassing it. If you're familiar with the concept of inheritance, skip to the next section.

Inheritance

Here is the definition for the Label class (mx.controls.Label) that was made possible with the new class keyword:

class mx.controls.Label extends UIObject {
...
}
          

Note the right-hand side of this statement—in particular the keyword extends. This phrase sets up the inheritance chain by making the class UIObject the superclass of Label. At compile-time and runtime, any methods or properties not defined in Label will be looked for by the compiler in UIObject, and so on until you reach the first superclass. If a method or property is not found then, the compiler returns an error.

Label is but one example of inheritance at work. Inheritance facilitates the development of classes and objects that specialize in performing functional tasks for better code reuse. Understanding inheritance provides a basis for understanding and developing Macromedia MX components.

Find more information about inheritance in Using Components in Flash Help.

Events

The event model is a dispatcher/listener model based on the DOM Level 3 proposal for event architectures. Every component in the architecture emits events in a standard format, as defined by the convention. Those events vary across components, depending on the functionality the component provides.

Components leverage the EventDispatcher mix-in (mx.events.EventDispatcher) to maintain a list of listeners that receive events when they are broadcast.

An event listener can be any object or method that conforms to the prescribed syntax, which accepts an event object as a parameter. An event object is a loosely typed object containing specific properties that carry information about the event—including its type, target, and, optionally, relevant information about the state change the event's emission represents.

Upon receiving the event, the listener code uses this event information to determine the actions to perform. Here's an example of an event listener:

listenerObject.eventName = function(evtObj){
  // your code here
	this._x += 10;
};
componentInstance.addEventListener("eventName", listenerObject);
          

In this code, the keyword this, if used in the callback function, is scoped to the listenerObject.

While every component can define unique events, events are inherited along the prototype chain. The core classes of the architecture, mx.core.UIObject and mx.core.UIComponent, define low-level component events like draw, resize, move, load, and others that are fundamental to all components. Subclasses of these classes inherit and broadcast these events.

Find more information about events, handling syntaxes, and the mix-in classes that enable event broadcasting in Using Components in Flash Help.

Understanding UIObject and UIComponent

UIObject and UIComponent base classes

UIObject and UIComponent are the base classes of the v2 component architecture. Both define methods and properties that all other components share, including a system for component creation. Understanding the principles at work in these two classes is important for building components.

UIObject (mx.core.UIObject)

UIObject directly subclasses MovieClip. By providing a wrapper around its methods and properties, it makes the syntax more intuitive and improves the conceptual management of representing graphic objects with movie clips.

A UIObject or UIObject subclass resizes itself by scaling. When you change its size using the size() method, the new dimensions are handed to the _width and _height movie clip properties, which scale the subclass.

The UIObject and UIObject subclasses broadcast their events just before drawing, analogous to the enterFrame() movie clip event. UIObject also defines the styling, skinning, and event aspects of the component architecture.

UIComponent (mx.core.UIComponent)

UIComponent is a subclass of UIObject. It defines high-level behaviors that are specific to a graphic object. UIComponent handles end-user interactions (clicking, dragging, focus, etc.) and component enabling and disabling. It also offers the draw() method, which you can override to customize how UIComponent handles calls to its size() method. UIComponent inherits all the methods, properties, and events of UIObject.

Considerations When Subclassing UIObject or UIComponent

Each component subclass defines methods that are specific to its task as a component, but there are a few methods that every component implements, which guarantee that the component takes advantage of system-level services provided by UIObject and UIComponent:

Using View Components

Components of the View class

Components that subclass the View class inherit methods that help manage child objects, including their creation, layout, and destruction. This distinction is useful—almost critical—when you build components that hold other components or objects, especially when they must adhere to a certain layout that constrains them or when you don't know until runtime what kinds of objects the container holds.

The View class makes it much easier to develop container components because component authors don't need to worry about writing the code that handles the management of child objects. It's built-in.

Window, Loader, Accordion, Alert, and Label are all view components.

Considerations When Subclassing View (mx.core.View)

Although each view subclass can define its own functionality through specific methods, there are important methods that every View subclass should implement by convention:

Using Managers and Mix-ins

The v2 component architecture features a set of managers (system-level static classes) and mix-ins (classes that decorate other classes with methods useful for a specific task). These classes help component and application developers by providing common, reusable pieces of functionality.

Following is a selection of managers and mix-ins included in the v2 architecture.

DepthManager (mx.managers.DepthManager)
The DepthManager class adds functionality to the ActionScript MovieClip class, which allows you to manage the relative depth assignments of any component or movie clip, including _root. It also allows you to manage reserved depths in a special highest-depth clip on the _root for system-level services like the cursor or tooltips.

FocusManager (mx.managers.FocusManager)
The FocusManager class keeps track of the currently focused item and how focus changes based on various user input events: keystrokes, Enter, Tab, or mouse-click. All components implement FocusManager support; you don't need to write code to invoke it. FocusManager also interacts with SystemManager, which activates and deactivates FocusManager instances as pop-up windows are activated or deactivated. Because each modal window has an instance of FocusManager, the components in that window become their own tab set, preventing users from tabbing into components in other windows.

PopUpManager (mx.managers.PopUpManager)
The PopUpManager class allows you to create overlapping windows that are modal or nonmodal. (A modal window doesn't allow interaction with other windows while it's active.) You can call PopUpManager.createPopUp() to create an overlapping window and call PopUpManager.deletePopUp() on the window instance to destroy a pop-up window.

StyleManager (mx.styles.StyleManager)
The StyleManager class keeps track of known styles and colors that you can apply to a given component as properties of that component. Use this class when you want to add a new inheriting style or color to a component you've created. The style properties (font styles, border colors, and many more) that are built in to StyleManager are based on a subset of the Cascading Style Sheets specification of the W3C. To determine which styles are supported in particular, investigate the StyleManager source code.

EventDispatcher and UIEventDispatcher (mx.events.EventDispatcher, mx.Events.UIEventDispatcher)
The EventDispatcher classes are mix-ins: They are meant to be mixed in with another class to give classes event-dispatching abilities. Similar to the native ASBroadcaster method, these event dispatchers feature an initialize() method, which takes as a parameter an object instance to which you attach methods that are specific to generating events and managing listener lists.

Find more information on the set of managers and mix-ins in Using Components in Flash Help.

About the author

Waleed Anbar is a Flash designer and developer who writes often for the Adobe Developer Center.