Monday, July 23, 2007

Creating visual Flex components in ActionScript

You can use ActionScript to programmatically create visual Flex components using the new operator, in the same way that you create instances of any ActionScript class. The created component has default values for its properties, but it does not yet have a parent or any children (including any kind of internal DisplayObjects), and it is not yet on the display list in Flash Player, so you can't see it. After creating the component, you should use standard assignment statements to set any properties whose default values aren't appropriate.

Finally, you must add the new component to a container, by using that container's addChild() or addChildAt() method, so that it becomes part of the visual hierarchy of a Flex application. The first time that it is added to a container, a component's children are created. Children are created late in the component's life cycle so that you can set properties that can affect children as they are created.

When creating visual controls, you must import the appropriate package. In most cases, this is the mx.controls package, although you should check Adobe Flex 2 Language Reference.

The following example creates a Button control inside the HBox:
<?xml version="1.0"?>

<!--
usingas/ASVisualComponent.mxml -->
<
mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<
mx:Script><![CDATA[
import
mx.controls.Button;

public var
button2:Button;

public function
createObject():void {

button2 = new Button();
button2.label = "Click Me";

hb1.addChild(button2);
}
]]></
mx:Script>
<
mx:HBox id="hb1">

<
mx:Button label="Create Object" click="createObject()"/>
</
mx:HBox>

</
mx:Application>


Flex creates the new child as the last child in the container. If you do not want the new child to be the last in the container, use the addChildAt() method to change the order. You can the setChildIndex() method after the call to the addChild() method, but this is less efficient.

You should declare an instance variable for each dynamically created component and store a reference to the newly created component in it, just as the MXML compiler does when you set an id property for a component instance tag. You can then access your dynamically created components in the same way as those declaratively created in MXML.

To programmatically remove a control, you can use the removeChild() or removeChildAt() methods. You can also use the removeAllChildren() method to remove all child controls from a container. Calling these methods does not actually delete the objects. If you do not have any other references to the child, Flash Player includes it in garbage collection at some future point. But if you stored a reference to that child on some object, the child is not removed from memory.

In some cases, you declaratively define a component with an MXML tag. You can set the creationPolicy property of the component's container to none to defer the creation of the controls inside that container. Then, to create a component that has been declared with a tag but not instantiated, you use the createComponentFromDescriptor() and createComponentsFromDescriptors() methods. These methods let you create a component programmatically rather than declaratively. For information on using the creationPolicy property, see Improving Startup Performance in Building and Deploying Flex 2 Applications.

The only component you can pass to the addChild() method is a UIComponent. In other words, if you create a new object that is not a subclass of mx.core.UIComponent, you must wrap it in a UIComponent before you can attach it to a container. The following example creates a new Sprite object, which is not a subclass of UIComponent, and adds it as a child of the UIComponent before adding it to the Panel container:

<?xml version="1.0"?>

<!--
usingas/AddingChildrenAsUIComponents.mxml -->
<
mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<
mx:Script><![CDATA[
import
flash.display.Sprite;

import
mx.core.UIComponent;

private function
addChildToPanel():void {

var
circle:Sprite = new Sprite();
circle.graphics.beginFill(0xFFCC00);

circle.graphics.drawCircle(0, 0, 20);

var
c:UIComponent = new UIComponent();
c.addChild(circle);

panel1.addChild(c);

}
]]></
mx:Script>

<
mx:Panel id="panel1" height="100" width="100"/>

<
mx:Button id="myButton" label="Click Me" click="addChildToPanel();"/>


</
mx:Application>

No comments: