Using containers

The rectangular region of a container encloses its content area, the area that contains its child components. The size of the region around the content area is defined by the container. That region can include extra space, or padding, around the content area and an optional border around the container.

The following image shows a container and its content area, padding, and borders:

A container and its content area, padding, and borders
A.
Left padding

B.
Right padding

C.
Container

D.
Content area

E.
Top padding

F.
Bottom padding

Although you can create an entire application by using a single container, typical applications use multiple containers. For example, the following image shows an application that uses three containers:

An application that uses three layout containers
A.
Parent container

B.
Child containers

In this example, the two child containers are nested within a parent container and are referred to as children of the parent container. The child containers themselves contain child UI components.

The parent container in the previous figure arranges its children in a single horizontal row and oversees the sizing and positioning characteristics of the child containers. For example, you can control the distance, or gap, between children in a container by using the horizontalGap and verticalGap properties. The two child containers are responsible for laying out their own children.

The following image shows the preceding example with the parent container configured to use a vertical layout:

The outermost container changed to a VBox layout container
A.
Parent container

B.
Child containers

The primary use of a container is to arrange its children, where the children are either controls or other containers. The following image shows a Spark Panel container that has three child components:

VBox container that has three child components
A.
TextInput control

B.
Button control

C.
TextArea control

In this example, a user enters a ZIP code into the TextInput control, and then clicks the Button control to see the current temperature for the specified ZIP code in the TextArea control.

Flex supports form-based applications through its MX Form layout container. In a Form container, Flex can automatically align labels, uniformly size text input controls, and display input error notifications. The following image shows a Form container:

Form container
A.
Form container

B.
TextInput control

C.
ComboBox control

D.
Button control

Navigator containers, such as the MX TabNavigator and MX Accordion containers, have built-in navigation controls that let you organize information from multiple child containers in a way that makes it easy for a user to move through it. The following image shows an Accordion container:

View full size graphic
A. Accordion buttons

You use the Accordion buttons to move among the different child containers. The Accordion container defines a sequence of child panels, but displays only one panel at a time. To navigate a container, the user clicks the navigation button that corresponds to the child panel that they want to access.

Accordion containers support the creation of multistep procedures. The preceding image shows an Accordion container that defines four panels of a complex form. To complete the form, the user enters data into all four panels. Accordion containers let users enter information in the first panel, click the Accordion button to move to the second panel, and then move back to the first if they want to edit the information. For more information, see MX Accordion navigator container.

Spark containers

The following table describes the Spark containers defined in the spark.components package:

Container

Type

Description

For more information

Application

Layout

The first container in an application. The default layout is absolute.

Application containers

BorderContainer

Layout

Defines a set of CSS styles that control the appearance of the border and background fill of the container.

The Spark BorderContainer container

DataGroup

Layout

Simple container that lays out it children, including data items, based on the specified layout. The default layout is absolute.

The Spark DataGroup and Spark SkinnableDataContainer containers

Group

Layout

Simple container that lays out it children, including graphic children, based on the specified layout. The default layout is absolute.

Flex defines subclasses of Group: HGroup with horizontal layout, VGroup with vertical layout, and TileGroup with tile layout.

The Spark Group and Spark SkinnableContainer containers

NavigatorContent

Layout

Simple container that can be used in an MX navigator container, such as the ViewStack, TabNavigator and Accordion containers.

The Spark NavigatorContent container

Panel

Layout

Displays a title bar, a caption, a border, and its children. The default layout is absolute.

The Spark Panel container

SkinnableContainer

Layout

Skinnable container that lays out it children, including graphic children, based on the specified layout. This container supports skinning. The default layout is vertical.

The Spark Group and Spark SkinnableContainer containers

SkinnableDataContainer

Layout

Skinnable container that lays out it children, including data items, based on the specified layout. This container supports skinning. The default layout is vertical.

The Spark DataGroup and Spark SkinnableDataContainer containers

SkinnablePopUpContainer

Layout

Skinnable container that lays out its children in a skinnable container opened as a pop up window.

The Spark SkinnablePopUpContainer container

TitleWindow

Layout

Skinnable Panel container that is optimized for use as a pop-up window.

The Spark TitleWindow container

MX containers

The following table describes the MX containers defined in the mx.core and mx.components packages:

Container

Type

Description

For more information

Accordion

Navigator

Organizes information in a series of child panels, where one panel is active at any time.

MX Accordion navigator container

Application

Layout

The first container in an application. The default layout is absolute.

Application containers

ApplicationControlBar

Layout

Holds components that provide global navigation and application commands. Can be docked at the top of an Application container.

MX ApplicationControlBar layout container

Box (HBox and VBox)

Layout

Displays content in a uniformly spaced row or column. An HBox container horizontally aligns its children; a VBox container vertically aligns its children.

Adobe recommends that you use the Spark containers when possible, instead of the MX Box container.

MX Box, HBox, and VBox layout containers

Canvas

Layout

Defines a container in which you must explicitly position its children.

Adobe recommends that you use the Spark containers with BasicLayout when possible, instead of the MX Canvas container.

MX Canvas layout container

ControlBar

Layout

Places controls at the lower edge of a Panel or TitleWindow container.

MX ControlBar layout container

DividedBox (HDividedBox and VDividedBox)

Layout

Lays out its children horizontally or vertically, much like a Box container, except that it inserts an adjustable divider between the children.

MX DividedBox, HDividedBox, and VDividedBox layout containers

Form

Layout

Arranges its children in a standard form format.

MX Form, FormHeading, and FormItem layout containers

Grid

Layout

Arranges children as rows and columns of cells, much like an HTML table.

MX Grid layout container

Panel

Layout

Displays a title bar, a caption, a border, and its children.

Adobe recommends that you use the Spark Panel container when possible, instead of the MX Panel container.

MX Panel layout container

TabNavigator

Navigator

Displays a container with tabs to let users switch between different content areas.

MX TabNavigator container

Tile

Layout

Defines a layout that arranges its children in multiple rows or columns.

Adobe recommends that you use the Spark containers with the TileLayout when possible, instead of the MX Tile container.

MX Tile layout container

TitleWindow

Layout

Displays a popup window that contains a title bar, a caption, border, a close button, and its children. The user can move the container.

MX TitleWindow layout container

ViewStack

Navigator

Defines a stack of containers that displays a single container at a time.

MX ViewStack navigator container

Container example

The following example creates an application that uses a Spark Group container with three child controls, where the Group container lays out its children vertically:

<?xml version="1.0"?>
<!-- containers\intro\Panel3Children.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:Group>
        <s:layout>
            <s:VerticalLayout/>
        </s:layout>
        <s:TextInput id="myinput" text="enter zip code"/>
        <s:Button id="mybutton" label="GetWeather"/>
        <s:TextArea id="mytext" height="20"/>
    </s:Group>
</s:Application>

The executing SWF file for the previous example is shown below:

The Group container uses basic layout by default. Use the layout property of a Spark container to configure its layout. In the previous example, you set the layout of the Group container to vertical.

The Group container has subclasses that you can use as shortcuts in your application: HGroup defines a Group container with horizontal layout, VGroup defines a Group container with veritical layout, and TileGroup defines a Group container with tile layout. The following example modifies the previous example to use the VGroup container:
<?xml version="1.0"?>
<!-- containers\intro\Panel3Children.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

    <s:VGroup>
        <s:TextInput id="myinput" text="enter zip code"/>
        <s:Button id="mybutton" label="GetWeather"/>
        <s:TextArea id="mytext" height="20"/>
    </s:VGroup>
</s:Application>

The executing SWF file for the previous example is shown below:

To actually retrieve weather information, you must set up a web service, pass it the entered ZIP code from a click event, and use the returned information to populate the TextArea control.

Using container events

All containers and components support events. Containers dispatch the following events:

Spark container

MX container

Description

elementAdd

childAdd

Dispatched after a child is added to the container.

elementRemove

childRemove

Dispatched before a child is removed from the container.

 

childIndexChanged

Dispatched after a child’s index in the container has changed.

Spark containers dispatch multiple itemAdd and itemRemove events.

 

scroll

Dispatched when the user manually scrolls the container.

contentCreationComplete

 

Dispatched after all container children are created, and before the children dispatch the creationComplete event. This event is not available for Group and DataGroup.

All components dispatch the following events after they are added to or removed from a container:

Event

Description

add

Dispatched by a component after the component has been added to its container and the parent and the child are in a consistent state. This event is dispatched after the container has dispatched the childAdd event and all changes that need to be made as a result of the addition have happened.

remove

Dispatched by a component after the component has been removed from its parent container. This event is dispatched after the container has dispatched the childRemove event and all changes that need to be made as a result of the removal have happened.

Several events are dispatched by all components, but need special consideration when dispatched by containers. This is particularly true for navigator containers, such as TabNavigator, where some children might not be created when the container is created. These events include the following:

Event

Description

preinitialize

Dispatched when the component has been attached to its parent container, but before the component has been initialized, or any of its children have been created. In most cases, this event is dispatched too early for an application to use to configure a component.

initialize

Dispatched when a component has finished its construction and its initialization properties have been set. At this point, all the component’s immediate children have been created (they have at least dispatched their preinitialize event), but they have not been laid out. Exactly when initialize events are dispatched depends on the container’s creation policy.

Flex dispatches the initialize event for a container after it attaches all the container’s direct child controls and the container’s initially required children have dispatched a preinitialize event.

When a container or control dispatches the initialize event, its initial properties have been set, but its width and height have not yet been calculated, and its position has not been calculated. The initialize event is useful for configuring a container’s children. For example, you can use the container’s initialize event to programmatically add children or set a container scroll bar’s styles. You can use a container or component’s initialize event to initialize the data provider for a control.

creationComplete

Dispatched when the component, and all its child components, and all their children, and so on, have been created, laid out, and are visible.

Flex dispatches the creationComplete event for a container when those children that are initially required are fully processed and drawn on the screen, including all required children of the children, and so on. Create a listener for the creationComplete event, for example, if you must have the children’s dimensions and positions in your event handler. Do not use the creationComplete event for actions that set layout properties, as doing so results in excess processing time.

The following example uses the creationComplete event to open an Alert box when the children of the HGroup container are fully processed and drawn:
<?xml version="1.0"?>
<!-- containers\intro\Panel3ChildrenEvent.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    
    <fx:Script>
        <![CDATA[
            import mx.controls.Alert;
            
            private function handleCreationComplete():void {
                Alert.show("MyHGroup created.");
            }
        ]]>
    </fx:Script>

    <s:HGroup id="MyHGroup" 
        creationComplete="handleCreationComplete();"> 
        <s:TextInput id="myinput" text="enter zip code"/>
        <s:Button id="mybutton" label="GetWeather"/>
        <s:TextArea id="mytext" height="20"/>
    </s:HGroup> 
</s:Application>

The executing SWF file for the previous example is shown below:

To better understand the order in which Flex dispatches events, consider the following application outline.

OuterSkinnableContainer 
    InnerSkinnableContainer1 
        InnerLabel1 
    InnerSkinnableContainer2 
        InnerLabel2

The preinitialize, initialize, contentCreationComplete, and creationComplete events for the containers and controls are dispatched in the following order. The indentation corresponds to the indentation in the previous outline:

OuterSkinnableContainer preinitialize 
    InnerSkinnableContainer1 preinitialize 
        InnerLabel1 preinitialize 
        InnerLabel1 initialize 
    InnerSkinnableContainer1 contentCreationComplete 
    InnerSkinnableContainer1 initialize 
    InnerSkinnableContainer2 preinitialize 
        InnerLabel2 preinitialize 
        InnerLabel2 initialize 
    InnerSkinnableContainer2 contentCreationComplete 
    InnerSkinnableContainer2 initialize 
OuterSkinnableContainer contentCreationComplete 
OuterSkinnableContainer initialize 
        InnerLabel2 creationComplete 
        InnerLabel1 creationComplete 
    InnerSkinnableContainer2 creationComplete 
    InnerSkinnableContainer1 creationComplete 
OuterSkinnableContainer creationComplete

Notice that for the terminal controls, such as the Label controls, the controls are preinitialized and then immediately initialized. For containers, preinitialization starts with the outermost container and works inward on the first branch, and then initialization works outward on the same branch. This process continues until all initialization is completed.

Then, the creationComplete event is dispatched first by the leaf components, and then by their parents, and so on, until the application dispatches the creationComplete event. The order of the creationComplete event is the most deeply nested components dispatch the event first, then the next most deeply nested, up to the application container. For components at the same nesting level, the order of the creationComplete events is undefined.

The initialize event is useful with a container that is an immediate child of a navigator container with the ContainerCreationPolicy.AUTO creation policy. For example, by default, when an MX ViewStack is initialized, the first visible child container dispatches an initialize event. Then, as the user moves to each additional child of the container, the event gets dispatched for that child container.

The following example defines an event listener for the creationComplete event, which is dispatched when the user first navigates to Pane 2 of an MX Accordion navigator container:

<?xml version="1.0"?>
<!-- containers\intro\AccordionInitEvent.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">

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

            public function pane2_initialize():void {
                Alert.show("Pane 2 has been created.");
            }
        ]]>
    </fx:Script>

    <mx:Accordion width="200" height="100" creationPolicy="auto">
        <mx:VBox id="pane1" label="Pane 1">
            <mx:Label text="This is pane 1."/>
        </mx:VBox>
        <mx:VBox id="pane2" 
            label="Pane 2" 
            creationComplete="pane2_initialize();">
            <mx:Label text="This is pane 2."/>
        </mx:VBox>
    </mx:Accordion>
</s:Application>

The executing SWF file for the previous example is shown below:

Disabling containers

All containers support the enabled property. By default, this property is set to true to enable user interaction with the container and with the container’s children. If you set enabled to false, Flex dims the color of the container and of all its children, and blocks user input to the container and to all its children.

Defining a default button

You use the defaultButton property of a container to define a default Button control within a container. Pressing the Enter key while focus is on any control activates the Button control as if it was explicitly selected.

For example, a login form displays TextInput controls for a user name and password and a submit Button control. Typically, the user types a user name, tabs to the password field, types the password, and presses the Enter key to submit the login information without explicitly selecting the Button control. To define this type of interaction, set the defaultButton property of the Form control to the id of the submit Button control, as the following example shows:

<?xml version="1.0"?>
<!-- containers\intro\ContainerDefaultB.mxml -->
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
    xmlns:mx="library://ns.adobe.com/flex/mx" 
    xmlns:s="library://ns.adobe.com/flex/spark">
    <s:layout>
        <s:VerticalLayout/>
    </s:layout>
    
    <fx:Script>
        <![CDATA[
            public function submitLogin():void {
                text1.text="You just tried to log in.";
            }
        ]]> 
    </fx:Script>

    <s:Panel title="Default Button Example">
        <s:Form defaultButton="{mySubmitBtn}">
            <s:FormItem label="Username:">
                <s:TextInput id="username" width="100"/>
            </s:FormItem>
            <s:FormItem label="Password:">
                <s:TextInput id="password" width="100" 
                    displayAsPassword="true"/>
            </s:FormItem>
            <s:FormItem>
                <s:Button id="mySubmitBtn" label="Login" 
                    click="submitLogin();"/>
            </s:FormItem>
        </s:Form>
    </s:Panel>
    <s:Label id="text1" width="150"/>
</s:Application>

The executing SWF file for the previous example is shown below:

Note: The Enter key has a special purpose in the ComboBox control. When the drop-down list of a ComboBox control is open, pressing Enter selects the currently highlighted item in the ComboBox control; it does not activate the default button. Also, when the cursor is in a TextArea control, pressing Enter adds a newline; it does not activate the default button.