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 padding and the width of the container border. A container has top, bottom, left, and right padding, each of which you can set to a pixel width. A container also has properties that let you specify the type and pixel width of the border. The following image shows a container and its content area, padding, and borders:
Although you can create an entire Flex application by using a single container, typical applications use multiple containers. For example, the following image shows an application that uses three layout containers:
In this example, the two VBox (vertical box) layout containers are nested within an HBox (horizontal box) layout container and are referred to as children of the HBox container.
The HBox container arranges its children in a single horizontal row and oversees the sizing and positioning characteristics of the VBox containers. For example, you can control the distance, or gap, between children in a container by using the horizontalGap and verticalGap properties.
A VBox container arranges its children in a single vertical stack, or column, and oversees the layout of its own children. The following image shows the preceding example with the outermost container changed to a VBox layout container:
In this example, the outer container is a VBox container, so it arranges its children in a vertical column.
The primary use of a layout container is to arrange its children, where the children are either controls or other containers. The following image shows a simple VBox container that has three child components:
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 Form layout container. In a Form container, Flex can automatically align labels, uniformly size TextInput controls, and display input error notifications. The following image shows a Form container:
Form containers can take advantage of the Flex validation mechanism to detect input errors before the user submits the form. By detecting the error, and letting the user correct it before submitting the form to a server, you eliminate unnecessary server connections. The Flex validation mechanism does not preclude you from performing additional validation on the server. For more information on Form containers, see Form, FormHeading, and FormItem layout containers. For more information on validators, see Validating Data.
Navigator containers, such as the TabNavigator and 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:
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 on 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 Accordion navigator container.
The following table describes the Flex containers:
|
Container |
Type |
Description |
For more information |
|---|---|---|---|
|
Accordion |
Navigator |
Organizes information in a series of child panels, where one panel is active at any time. |
|
|
Application |
Layout |
Holds components that provide global navigation and application commands. Can be docked at the top of an Application 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. |
|
|
Canvas |
Layout |
Defines a container in which you must explicitly position its children. |
|
|
ControlBar |
Layout |
Places controls at the lower edge of a Panel or TitleWindow 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. |
|
|
Form |
Layout |
Arranges its children in a standard form format. |
|
|
Grid |
Layout |
Arranges children as rows and columns of cells, much like an HTML table. |
|
|
Panel |
Layout |
Displays a title bar, a caption, a border, and its children. |
|
|
TabNavigator |
Navigator |
Displays a container with tabs to let users switch between different content areas. |
|
|
Tile |
Layout |
Defines a layout that arranges its children in multiple rows or columns. |
|
|
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. |
|
|
ViewStack |
Navigator |
Defines a stack of containers that displays a single container at a time. |
Flex containers are implemented as a hierarchy in an ActionScript class library, as the following image shows:
All containers are derived from the ActionScript classes Sprite, UIComponent, and Container, and therefore inherit the properties, methods, styles, effects, and events of their superclasses. Some containers are subclasses of other containers; for example, the ApplicationControlBar is a subclass of the ControlBar container. For complete reference information, see the Adobe Flex Language Reference.
The following image shows a Flex application that uses a Panel container with three child controls, where the Panel container lays out its children vertically:
The following MXML code creates this example:
<?xml version="1.0"?>
<!-- containers\intro\Panel3Children.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel title="My Application"
layout="vertical" horizontalAlign="center"
paddingLeft="10" paddingRight="10"
paddingTop="10" paddingBottom="10">
<mx:TextInput id="myinput" text="enter zip code"/>
<mx:Button id="mybutton" label="GetWeather"/>
<mx:TextArea id="mytext" height="20"/>
</mx:Panel>
</mx:Application>
The executing SWF file for the previous example is shown below:
The following image shows the preceding example implemented by using a Panel container with a horizontal layout:
The only difference between these examples is the container type and the increased width of the Application container caused by the horizontal layout, as the following code shows:
<?xml version="1.0"?>
<!-- containers\intro\Panel3ChildrenHoriz.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Panel title="My Application"
layout="horizontal"
paddingLeft="10" paddingRight="10"
paddingTop="10" paddingBottom="10">
<mx:TextInput id="myinput" text="enter zip code"/>
<mx:Button id="mybutton" label="GetWeather"/>
<mx:TextArea id="mytext" height="20"/>
</mx:Panel>
</mx: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.
All containers and components support events.
The following events are dispatched only by containers:
The first three events are dispatched for each of the container's children, and the last is dispatched when the container scrolls. For detailed information on these events, see Container in the Adobe Flex Language Reference.
The following events are dispatched only by Application containers:
The following events are dispatched by all components after they are added to or removed from a container:
Several events are dispatched for all components, but need special consideration for containers, particularly navigator containers such as TabNavigator, where some children might not be created when the container is created. These events include the following:
For information on the initialize and creationComplete events, see About the initialize and creationComplete events. For information on the remaining events, see Container in the Adobe Flex Language Reference.
Containers have a creationPolicy property that specifies when its children are created. By default, containers have a creation policy of ContainerCreationPolicy.AUTO, which means that the container delays creating descendants until they are needed, a process which is known as deferred instantiation. (A container's default creation policy is derived from its parent's instantiation policy, and the Application container has a default policy of ContainerCreationPolicy.AUTO.)
An auto creation policy produces the best startup time because fewer components are created initially. For navigator containers such as the ViewStack, TabNavigator, and Accordion, an ContainerCreationPolicy.AUTO creation policy means that the container creates its direct children immediately, but waits to create the descendants of each child until the child needs to be displayed. As a result, only the initially required child or children of a container get processed past the preinitialization stage.
A creation policy of ContainerCreationPolicy.ALL requires all of a container's children to be fully created and initialized before the container is initialized. For detailed information on creation policies, see Improving Startup Performance.
About the initialize and creationComplete events
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 a 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.
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.
To better understand the order in which Flex dispatches events, consider the following application outline.
Application
OuterVBox
InnerVBox1
InnerVBoxLabel1
InnerVBox2
InnerVBoxLabel2
The preinitialize, initialize, and creationComplete events for the containers and controls are dispatched in the following order. The indentation corresponds to the indentation in the previous outline:
OuterVBoxpreinitialize
InnerVBox1preinitialize
InnerVBox1Labelpreinitialize
InnerVBox1Labelinitialize
InnerVBox1initialize
InnerVBox2preinitialize
InnerVBox2Labelpreinitialize
InnerVBox2Labelinitialize
InnerVBox2initialize
OuterVBoxinitialize
InnerBox1LabelcreationComplete
InnerVBox2LabelcreationComplete
InnerVBox1creationComplete
InnerVBox2creationComplete
OuterVBoxcreationComplete
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.
If you change the OuterVBox container to a ViewStack with a creationPolicy property set to auto, the events would look as follows:
OuterViewStackpreinitialize
InnerVBox1preinitialize
InnerVBox2preinitialize
OuterViewStackinitialize
InnerBox1Labelpreinitialize
InnerBox1Labelinitialize
InnerVBox1initialize
InnerBox1LabelcreationComplete
InnerVBox1creationComplete
OuterViewStackcreationComplete
In this case, the second VBox is preinitialized only, because it does not have to be displayed. Notice that when a navigator container dispatches the initialize event, its children exist and have dispatched the preinitialize event, but its children have not dispatched the initialize event because they have not yet created their own children. For more information on the creationPolicy property, see Improving Startup Performance.
The initialize event is useful with a container that is an immediate child of a navigator container with an ContainerCreationPolicy.AUTO creation policy. For example, by default, when a 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 initialize event, which is dispatched when the user first navigates to panel 2 of an Accordion container:
<?xml version="1.0"?>
<!-- containers\intro\AccordionInitEvent.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
import mx.controls.Alert;
public function pane2_initialize():void {
Alert.show("Pane 2 has been created.");
}
]]>
</mx:Script>
<mx:Accordion width="200" height="100">
<mx:VBox id="pane1" label="Pane 1">
<mx:Label text="This is pane 1."/>
</mx:VBox>
<mx:VBox id="pane2"
label="Pane 2"
initialize="pane2_initialize();">
<mx:Label text="This is pane 2."/>
</mx:VBox>
</mx:Accordion>
</mx:Application>
The executing SWF file for the previous example is shown below:
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 of its children, and blocks user input to the container and to all of its children.
One container that you often use in a Flex application is the Panel container. The Panel container consists of a title bar, a caption, a status message, a border, and a content area for its children. Typically, you use a Panel container to wrap self-contained application modules. For example, you can define several Panel containers in your application where one Panel container holds a form, a second holds a shopping cart, and a third holds a shopping catalog. The Flex RichTextEditor control is a Panel control that contains a TextArea control and a ControlBar control that has editing controls.
The following image shows a Panel container with a Form container as its child:
For more information on the Panel container, see Panel layout container.
You can also define a ControlBar control as part of a Panel container. A ControlBar control defines an area at the lower edge of the Panel container, below any children in the Panel container.
You can use the ControlBar container to hold components that might be shared by the other children in the Panel container, or for controls that operate on the content of the Panel container. For example, you can use the ControlBar container to display the subtotal of a shopping cart, where the shopping cart is defined in the Panel container. For a product catalog, the ControlBar container can hold the Flex controls to specify quantity and to add an item to a shopping cart. For more information on the ControlBar container, see ControlBar layout container.
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 -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:Script>
<![CDATA[
public function submitLogin():void {
text1.text="You just tried to log in.";
}
]]>
</mx:Script>
<mx:Panel title="Default Button Example">
<mx:Form defaultButton="{mySubmitBtn}">
<mx:FormItem label="Username:">
<mx:TextInput id="username" width="100"/>
</mx:FormItem>
<mx:FormItem label="Password:">
<mx:TextInput id="password" width="100" displayAsPassword="true"/>
</mx:FormItem>
<mx:FormItem>
<mx:Button id="mySubmitBtn" label="Login" click="submitLogin();"/>
</mx:FormItem>
</mx:Form>
<mx:Text id="text1" width="150"/>
</mx:Panel>
</mx:Application>
The executing SWF file for the previous example is shown below: