Learning Flex Basics (Part 3) : Working with Containers
Robert Crooks
In this tutorial you will work with navigation and layout containers to create an application with multiple views. You learn to use several layout containers and the TileList control, which provides a flexible way of presenting an array of data. You also learn how to use one of the new charting components in Macromedia Flex 1.5.
If you like what you see and want to get more experience with Flex,
Macromedia Customer Training offers Developing Rich Internet Applications with Macromedia Flex, a two-day onsite training course to jump-start Flex development in your organization. Now let's get started!
What you will learn
- How to use the Application tag.
- How to use the TabNavigator.
- How to use the ViewStack.
- How to use the LinkBar.
- How to use a Panel container.
- How to use the HBox.
- How to use the VBox.
- How to use the TileList control.
- How to use the LineChart component and its subcomponents.
- How to use Label controls.
- How to use Button controls.
- How to create an array in ActionScript.
- How to create an array of objects in ActionScript.
- How to create event handlers for events on list items in ActionScript.
Requirements
To complete this tutorial you will need to install the following software and files:
Macromedia Flex
A Text Editor
Flex Builder, Dreamweaver MX 2004, or a text editor that you can use to write XML and ActionScript code (a basic text editor such as Notepad is adequate). You can download Flex Builder with the Flex server try/buy links above. Use the following links to try/buy Dreamweaver MX 2004:
Solution files for the tutorial:
Prerequisite knowledge:
Building the Application
The application is simple. The tutorial focuses on learning how to use navigation and layout containers. You will create a global navigation system for two main views using the TabNavigator container. In one of the main views you use the LinkBar and ViewStack navigator containers to create a local navigation system for two secondary views.
In the views, you use a variety of layout containers: Panel, HBox, and Form. You also learn how to use the TileList control to lay out an array of items and LineChart to present data.
Figure 1. Form View
Figure 2. Tile List
Figure 3. Line Chart
Create the Application Object
To begin any Flex application, start with an XML declaration and an Application block. The Application
tag will include a namespace declaration for the MX class library: xmlns:mx="http://www.macromedia.com/2003/mxml"
. The mx prefix is used with all tags for this library.
- Create a new file and save it as containers.mxml in the flex_tutorials directory.
-
At the beginning of the file, insert the XML declaration:
-
After the XML declaration, add an Application
tag with the MXML namespace:
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml">
</mx:Application>
Create a Data Array
In the
first tutorial you learn how to create an Array using tag syntax. Here you create one in ActionScript.
-
Inside the Application block, Script block with a CDATA wrapper to prevent the XML parser from trying to interpret the script as XML code:
<mx:Script>
<![CDATA[]]>
</mx:Script>
-
Inside the Script block, declare a variable called myArray
of type Array
, and set the values of the array items as [0,1,2,3,4,5,6,7,8,9]
:
var myArray=[0,1,2,3,4,5,6,7,8,9];
Create an Array of Objects
You also need an array of objects to populate one of the controls you will create, and to provide data for a charting component. You created an array of objects in the
first tutorial in this series, using tags nested inside the
<mx:Object>
tag to create the object properties. Here you will use an alternate syntax, using attributes of the
<mx:Object>
tag to create the properties.
- After the Script block, insert an
<mx:Array>
block:
<mx:Array id="myArrayOfObjects">
</mx:Array>
- Inside the
<mx:Array>
block, insert four <mx:Object>
tags with label, volume, and revenue properties as shown below:
<mx:Object label="Q1" volume="1600" revenue="10000"/>
<mx:Object label="Q2" volume="1500" revenue="9000"/>
<mx:Object label="Q3" volume="1900" revenue="12000"/>
<mx:Object label="Q4" volume="2300" revenue="14000"/>
Add a TabNavigator Container for Global Navigation
The TabNavigator container automatically creates navigation aids for layout containers nested inside it based on their label
values.
-
After the Script block, add a TabNavigator container with margin, height, and width values as follows:
<mx:TabNavigator id="tabNav" marginLeft="10" marginTop="20">
</mx:TabNavigator>
Add an HBox Layout and Panel Containers for Main Views
The Flex class library contains a number of layout container classes for arranging contents visually on the screen. Here you use two of them for the main navigation views:
- HBox layout container lays out its contents in a row
- Panel container (also used in the first two tutorials), lays out contents horizontally or vertically, and provides a title bar
For the Panel, use data binding to link the height of the Panel container to the height of the TabNavigator container. This is a useful technique for creating relative sizing and minimizing hard-coded sizes that would be tedious to maintain in later UI makeovers or in porting the application to a different display device. You achieve data binding here through curly braces: { and }. The curly braces indicate that the Flex compiler should evaluate the contents inside as an ActionScript expression or variable.
-
Inside the TabNavigator container block, add an HBox container block with the label "View 1: Form/Tile":
<mx:HBox label="View 1: Form/Tile" width="500" height="400">
</mx:HBox>
-
After the HBox container block, add a Panel container with the label View 2: Pseudo Bar Chart, and id
, height
, and title
properties as follows:
<mx:Panel label="View 2: Sales Trends Chart" title="Sales Trends">
</mx:Panel>
Add a ViewStack, LinkBar, and Panel Containers for Secondary Views
The base class for the TabNavigator container is the ViewStack navigator container, which contains an array of containers and lets you manage navigation between them through either the selectedIndex
or selectedItem
property (the first references a container by its position in the array, the second by its id value). The TabNavigator container extends the ViewStack class, and so has its ViewStack "built-in"; other navigation containers use a separately defined ViewStack container as a dataProvider, but still provide the transparent handling of navigation.
In setting the height and width for the ViewStack container, you use a new feature in Flex 1.5: percentage-based dimensions. You can now set width and height as specific pixel values or as percentages of the corresponding dimension of the bounding container (within the limits of the available space left by other contents within the bounding container).
The LinkBar navigator container has a direction property that you can set to horizontal or vertical, making it useful for either global or section navigation; here you use it for the latter.
-
Inside the HBox container, add a ViewStack container with the id vStack :
<mx:ViewStack id="vStack" width="80%" height="100%">
</mx:ViewStack>
-
Before the ViewStack container, but still inside the HBox container, add a LinkBar container with a dataProvider bound to the ViewStack container and direction attribute set to vertical:
<mx:LinkBar dataProvider="{vStack}" direction="vertical"/>
-
Inside the ViewStack container, add two Panels, the first has both title
and label
properties set to Form; the second has title
and label
set to Tile and an id
of tilePanel:
<mx:Panel title="Form" label="Form">
</mx:Panel><mx:Panel id="tilePanel" title="Tile" label="Tile" width="220" height="210">
</mx:Panel>
- Save the file and browse it. Click the two tabs and the two links of the LinkBar container to see the automatic handling of navigation. Also try the browser's back and forward buttons; the navigation containers tie navigation events to the browser's history so that the back and forward buttons work just as they would if these were normal web pages.
Add a Form Container
The navigation of our simple application is now complete, and for the rest of the tutorial you focus on the use of layout containers. First, you create a Form container, which automatically arranges form controls and also provides some aids for handling the processing of form data (which you won't use here, but are straightforward and covered in the
Flex documentation). You can use ordinary event handlers for form data also, as you do in this exercise.
The Form works with two nested container classes:
- FormHeading: Creates one or more headings (this is optional - you can use Labels as well)
- FormItem: Creates labels for a control or a group of controls
You also create a ControlBar container in this section. A ControlBar is an optional footer container for a Panel with a horizontal layout.
-
Inside the Panel with the title "Form," add a Form container:
-
Inside the Form, add a FormHeading with the label My Form:
<mx:FormHeading label="My Form"/>
-
After the FormHeading, add a FormItem container block with the label Pick a Number:
<mx:FormItem label="Pick a Number">
</mx:FormItem>
-
Inside the FormItem, add a ComboBox with the id
of myCombo and the dataProvider property bound to myArray
:
<mx:ComboBox id="myCombo" dataProvider="{myArray}"/>
-
After the Form container, but still inside the Panel, add a ControlBar container:
<mx:ControlBar>
</mx:ControlBar>
-
Inside the ControlBar container, add a Label whose text is the string "You chose: " joined to a binding to the selectedItem
property of the ComboBox:
<mx:Label text="You chose: {myCombo.selectedItem}"/>
- Save the file and browse it to see the form; select an different item in the ComboBox to see the Label in the ControlBar container change.
Add a TileList and Populating It with an Array of Objects
For the second view in the first main view, you use a TileList control, which lays out items from a dataProvider in rows or columns. In other respects, the TileList is similar to the List and ComboBox controls you have used previously. The MouseOver and MouseDown behaviors are built in (and you can modify them), and you can use the change event to fire an event handler.
-
Inside the Panel with the title "Tile," add a TileList control with a dataProvider bound to myArrayOfObjects
, width and height both set to 100%, and the change event set to setStatus(event.target.selectedItem)
:
<mx:TileList dataProvider="{myArrayOfObjects}"
change="setStatus(event.target.selectedItem)" width="100%" height="100%"/>
-
Inside the script block at the top of the application, add function block for the setStatus()
function; the function takes a parameter called item of type Object
, and returns nothing:
function setStatus(item:Object):Void
{
}
-
Inside the function block, add a single line that sets the status property of the surrounding Panel to "Revenue: "+item.revenue+" Volume: "+item.volume
:
tilePanel.status="Revenue: "+item.revenue+" Volume: "+item.volume;
Note: Remember that the item passed to the function is the original data item associated with the repeated object where the event occurred.
- Save the file and browse it. Click the tiled items in the TileList to see the associated data displayed in the Panel container status area.
Create a LineChart Component
In the final part of this tutorial, you use one of the new charting components in Flex 1.5 to create a line chart from the array of objects. The LineChart uses embedded axis components and a series component to define the appearance of the chart.
-
Inside the View 2 Panel, add a <mx:LineChart>
component with the dataProvider bound to myArrayOfObjects
, with a height set to 100% of the height of the bounding panel:
<mx:LineChart dataProvider="{myArrayOfObjects}" height="100%">
</mx:LineChart>
-
Inside the <mx:LineChart>
tag block, add an <mx:horizontalAxis>
block:
<mx:horizontalAxis>
</mx:horizontalAxis>
-
Inside the <mx:horizontalAxis>
block, add a <mx:CategoryAxis>
tag with dataProvider bound to myArrayOfObjects
and the categoryField
set to the label
property of the objects:
<mx:CategoryAxis dataProvider="{myArrayOfObjects}"
categoryField="label"/>
-
Inside the <mx:LineChart>
block but after the <mx:horizontalAxis>
block, add a <mx:series>
block:
-
Inside the <mx:horizontalAxis>
block, add an <mx:Array>
block:
-
Inside the <mx:Array>
block, add two <mx:LineSeries>
tags to define the lines of chart. Each has the form curve; the yField and name values are set to correspond to the volume and revenue properties of the objects in the dataProvider:
<mx:LineSeries yField="volume" form="curve" name="Volume"/>
<mx:LineSeries yField="revenue" form="curve" name="Revenue"/>
-
That's the end of the exercise. Save the file and browse it. Try the buttons to see the bars in the graph scale up and down.
Complete Code Listing for containers.mxml
<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.macromedia.com/2003/mxml" >
<mx:Script>
<![CDATA[
// data array
var myArray=[0,1,2,3,4,5,6,7,8,9];
// handler for tile
function setStatus(item:Object):Void
{
tilePanel.status="Revenue: "+item.revenue+" Volume: "+item.volume;
}
]]>
</mx:Script>
<mx:Array id="myArrayOfObjects">
<mx:Object label="Q1" volume="1600" revenue="10000"/>
<mx:Object label="Q2" volume="1500" revenue="9000"/>
<mx:Object label="Q3" volume="1900" revenue="12000"/>
<mx:Object label="Q4" volume="2300" revenue="14000"/>
</mx:Array>
<!-- global navigation -->
<mx:TabNavigator id="tabNav" marginLeft="10" marginTop="20">
<!-- view 1 -->
<mx:HBox label="View 1: Form/Tile" width="500" height="400">
<!-- section navigation -->
<mx:LinkBar dataProvider="{vStack}" direction="vertical"/>
<mx:ViewStack id="vStack" width="80%" height="100%">
<!-- form view -->
<mx:Panel title="Form" label="Form">
<mx:Form>
<mx:FormHeading label="My Form"/>
<mx:FormItem label="Pick a Number">
<mx:ComboBox id="myCombo" dataProvider="{myArray}"/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar>
<mx:Label text="You chose: {myCombo.selectedItem}"/>
</mx:ControlBar>
</mx:Panel>
<!-- tile view -->
<mx:Panel id="tilePanel" title="Tile" label="Tile" width="220" height="210">
<mx:TileList dataProvider="{myArrayOfObjects}" change="setStatus(event.target.selectedItem)" width="100%" height="100%"/>
</mx:Panel>
</mx:ViewStack>
</mx:HBox>
<!-- view 2 -->
<mx:Panel label="View 2: Sales Trends Chart" title="Sales Trends">
<mx:LineChart dataProvider="{myArrayOfObjects}" height="100%">
<mx:horizontalAxis>
<mx:CategoryAxis dataProvider="{myArrayOfObjects}"
categoryField="label"/>
</mx:horizontalAxis>
<mx:series>
<mx:Array>
<mx:LineSeries yField="volume" form="curve" name="Volume"/>
<mx:LineSeries yField="revenue" form="curve" name="Revenue"/>
</mx:Array>
</mx:series>
</mx:LineChart>
<mx:ControlBar>
</mx:ControlBar>
</mx:Panel>
</mx:TabNavigator>
</mx:Application>
Where to Go from Here
Continue on to the following tutorials to learn more:
If you like what you see and want to get more experience with Flex,
Macromedia Customer Training offers Fast Track to Macromedia Flex, a two-day onsite training course to jump-start Flex development in your organization. You should also look at the informative set of sample applications in included with Flex; these illustrate the use of many Flex features.
About the author
Robert Crooks is the Director of Curriculum Development for Macromedia. He has written several courses on creating internet applications including the beta version of Fast Track to Macromedia Flex.