Prerequisite knowledge

You do not need extensive knowledge of Flex 3 or Flex 4.5 to complete this tutorial, but if you intend to incorporate aspects of the Flex Dashboard application into your own projects, then having a good understanding of Flex 3, and at least a basic understanding of what's new in Flex 4.5, is essential. You should also complete Part 1Part 2, and Part 3 of this series before beginning this one.

 

User level

Beginning

Required products

Flash Builder 4.7 Premium (Download trial)

This article is Part 4 of a four-part series in which you import the Flex 3 Dashboard demonstration application available on the Flex Developer Center into Flash Builder 4.5, and then migrate the application to Flex 4.5 to take advantage of the Flex 4.5 Spark architecture and components.
 
Although a key feature of Flex 4.5 is its support for creating mobile applications in Flex, this article series does not cover converting the Dashboard application to a mobile application. A future article series will cover creating a mobile Dashboard application. Also, although Flex 4.5 introduces locale-aware formatters, they will not be used in this article series because the Dashboard application does not involve localization.
 
Part 1 of this series described how to import the Flex 3 Dashboard into Flash Builder 4.5 make just enough changes to get it to compile and run. Part 2 began the process of migrating the Dashboard code to Flex 4.5 by modifying the application background and TabBar to make use of the new Flex 4.5 Spark components. Part 3 continued the migration and described changes required to have the application's ViewStack use the new Flex 4.5 Spark NavigatorContent container. Part 4.5 (this article) completes the migration by adding Spark Panel, List, DataGrid, and VGroup components as well as custom skins and states.
 
If it has been a while since you completed Parts 1 and 2, you may want to quickly refer to the opening sections of those articles for a review of the Dashboard application, how the conversion is organized, and some tips for following the steps.
 
The sample files for this article include Dashboard-Part4-Start.fxp, which you can use as a starting point for the steps that follow. This Flex project file includes all the steps through Part 3 in this series.
 

 
Implementing custom skins for the Pod minimize and maximize buttons

In this section you'll create two custom button skin classes for the maximize and minimize buttons located in the Pod title bar area. These skins will implement the maximizeRestoreButton and minimizeButton styles from styles.css.
 
  1. Right-click the skins folder in Package Explorer and select New > MXML Skin.
  2. For the maximize button, type CustomMaximizeButtonSkin as the Name, and select spark.components.ToggleButton as the Host Component.
  3. Ensure the Create As Copy Of setting is spark.skins.spark.ToggleButtonSkin and select Remove ActionScript Styling Code.
  4. Click Finish.
  5. Right-click the skins folder in Package Explorer again and select New > MXML Skin.
  6. For the minimize button, type CustomMinimizeButtonSkin as the Name, and select spark.components.Button as the Host Component.
  7. Ensure the Create As Copy Of setting is spark.skins.spark.ButtonSkin and select Remove ActionScript Styling Code.
  8. Click Finish.
Note: Recall that the maximize button uses the ToggleButton control because the Spark Button control does not support the selected property as the MX Button does. This property is necessary to switch between the maximized and restored states for the button display.
 
  1. To use these custom skin classes, set the skinClass properties for the buttons in CustomPanelSkin.mxml in the controlsHolder HGroup:
<s:HGroup id="controlsHolder" right="9" top="4" horizontalAlign="right" verticalAlign="middle" gap="3"> <s:Button id="minimizeButton" skinClass="skins.CustomMinimizeButtonSkin"/> <s:ToggleButton id="maximizeRestoreButton" skinClass="skins.CustomMaximizeButtonSkin"/> </s:HGroup>
  1. Open the CustomMinimizeButtonSkin.mxml and CustomMaximizeButtonSkin.mxml files.
  2. In both files, remove minWidth="21" minHeight="21" from the opening <s:SparkButtonSkin> tag.
  3. In both files, remove everything in layers 1 through 8. Basically, remove everything from the ending </s:states> tag until just before the ending </s:SparkButtonSkin> tag.
  4. In CustomMinimizeButtonSkin.mxml only, add the following, directly after the ending </s:states> tag:
<s:BitmapImage includeIn="up, down" width="14" height="14" source="@Embed(source='/assets/minimize_up.png')"/> <s:BitmapImage includeIn="over" width="14" height="14" source="@Embed(source='/assets/minimize_over.png')"/>
  1. In CustomMaximizeButtonSkin.mxml only, add the following, directly after the ending </s:states> tag:
<s:BitmapImage includeIn="up, down" width="14" height="14" source="@Embed(source='/assets/maximize_up.png')"/> <s:BitmapImage includeIn="over" width="14" height="14" source="@Embed(source='/assets/maximize_over.png')"/> <s:BitmapImage includeIn="upAndSelected, downAndSelected" width="14" height="14" source="@Embed(source='/assets/restore_up.png')"/> <s:BitmapImage includeIn="overAndSelected" width="14" height="14" source="@Embed(source='/assets/restore_over.png')"/>
  1. Save your changes and build the project.
When you launch the Dashboard you'll see that the Pod title bar area looks very much like the corresponding area in the Flex 3 Dashboard application.
 

 
Changes in the Pod custom skin to support minimizing Pods

Changes are necessary in CustomPanelSkin.mxml to support displaying pods in a minimized state. Some of these steps are intricate, so follow along carefully.
 
  1. Add support for the new minimized state by adding this line to the <s:states> tag:
<s:State name="minimized"/>
  1. Add excludeFrom="minimized" to the following three visual elements, which should not display in the minimized state:
<s:RectangularDropShadow id="dropShadow" blurX="10" blurY="10" alpha="1" distance="5" angle="0" color="#999999" left="0" top="5" right="5" bottom="0" excludeFrom="minimized"/> <s:Rect id="background" left="1" top="1" right="1" bottom="1" excludeFrom="minimized"> <s:Group id="contentGroup" width="100%" height="100%" minWidth="0" minHeight="0" excludeFrom="minimized">
You'll need to modify the updateDisplayList() function to check for null objects, because in the minimized state, excluded visual elements will not exist and will cause null object runtime errors.
 
  1. You can just replace the entire function definition in CustomPanelSkin.mxml with the one below:
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void { if (getStyle("borderVisible") == true) { border.visible = true; contents.left = contents.top = contents.right = contents.bottom = 1; if(background != null){ background.left = background.top = background.right = background.bottom = 1; } } else { border.visible = false; contents.left = contents.top = contents.right = contents.bottom = 0; if(background != null){ background.left = background.top = background.right = background.bottom = 0; } } if(dropShadow != null){ dropShadow.visible = getStyle("dropShadowVisible"); } var cr:Number = getStyle("cornerRadius"); var withControls:Boolean = (currentState == "disabledWithControlBar" || currentState == "normalWithControlBar"); if (cornerRadius != cr) { cornerRadius = cr; if(dropShadow != null){ dropShadow.tlRadius = cornerRadius; dropShadow.trRadius = cornerRadius; dropShadow.blRadius = withControls ? cornerRadius : 0; dropShadow.brRadius = withControls ? cornerRadius : 0; } setPartCornerRadii(topMaskRect, withControls); setPartCornerRadii(border, withControls); if(background != null){ setPartCornerRadii(background, withControls); } } if (bottomMaskRect) setPartCornerRadii(bottomMaskRect, withControls); borderStroke.color = getStyle("borderColor"); borderStroke.alpha = getStyle("borderAlpha"); if(backgroundFill != null){ backgroundFill.color = getStyle("backgroundColor"); backgroundFill.alpha = getStyle("backgroundAlpha"); } super.updateDisplayList(unscaledWidth, unscaledHeight); }
  1. Save your changes and build the project.
Now you can minimize, maximize, and restore the Dashboard pods, in the same manner as the Flex 3 application. However, dragging the pods does not work, which will be fixed when you convert the DragHighlight component next.
 

 
Changes to the DragHighlight component

The next step is to convert the DragHighlight component, which displays a highlight box when pods are dragged, to Flex 4.5. You will use a Spark BorderContainer to define the visual aspects of the drag highlight defined in the DragHighlight style in styles.css.
 
  1. Open src/com/esria/samples/dashboard/view/DragHighlight.mxml.
  2. Replace the <mx:Box> tag with the following:
<s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx" borderColor="#CCCCCC" borderWeight="3" borderStyle="solid" backgroundColor="#F3F3F3"/>
  1. Save your changes and build the project.
This is the only change necessary for the DragHighlight component. If you run the application now, you'll be able to drag Pods without a runtime error.
 

 
Changes to the PodContentBase class to extend the Spark VGroup

In the Flex 3 Dashboard application, the PodContentBase class extends the Flex 3 MX VBox container. To migrate to Flex 4.5, it will need to extend the Spark VGroup instead. Because it does not use a skin, the VGroup container has a lighter weight than the VBox container. The PodContentBase class is the base class of the ChartContent, FormContent, ListContent, and PieChartContent components, which represent the actual data for the pods.
 
  1. Open src/com/esria/samples/dashboard/view/PodContentBase.as.
  2. Locate the following line:
public class PodContentBase extends VBox
  1. Replace it with this line:
public class PodContentBase extends VGroup
  1. Locate the following line:
import mx.containers.VBox;
  1. Replace it with this line:
import spark.components.VGroup;
  1. Save your changes.
These are the only two changes necessary to the PodContentBase class. Note that launching and using the application now might result in empty pods or runtime errors, because although you have modified the PodContentBase class, you have not yet modified its subclasses.
 

 
Changes to the ChartContent component

This is the first of four sections in which you make changes to the ChartContent, PieChartContent, FormContent, and ListContent components, which extend the PodContentBase class and represent the actual data for the pods. All of these components are located in src/com/esria/samples/dashboard/view/.
 
Several steps in these sections are the same, but you will make changes to each component separately, because making changes to all four files at the same time would make it impossible to launch the application for an extended period of time due to multiple errors.
 
  1. To begin, open ChartContent.mxml.
  2. Update the namespace definition in the root tag by replacing: xmlns:mx=http://www.adobe.com/2006/mxml with the following lines:
xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"
  1. Change the namespace prefix from mx to fx for the <mx:Script> tag.
Note: When changing a tag from mx to fx (or in some cases, from mx to s ) here and throughout these steps, remember to change the associated closing tag as well; for example, change </mx:Script> to </fx:Script> .
 
  1. Change the namespace prefix from mx to fx for all <mx:Component> tags.
  2. Enclose the two effects defined in the file within an <fx:Declarations> tag, so non-visual elements can be distinguished from visual elements:
<fx:Declarations> <effects:DrillDownEffect id="drillDownEffect" duration="1500" effectEnd="chart.showDataTips=true" /> <effects:DrillUpEffect id="drillUpEffect" duration="1500" effectEnd="chart.showDataTips=true"/> </fx:Declarations>
  1. To use the Spark DropDownList instead of the MX ComboBox, replace the entire MX ComboBox declaration with this:
<s:DropDownList selectedIndex="{_selectedViewIndex}" change="onChangeComboBox(event)" width="100" fontSize="10" fontWeight="bold" fontFamily="verdana"> <s:ArrayList> <fx:String>Bar Chart</fx:String> <fx:String>Line Chart</fx:String> </s:ArrayList> </s:DropDownList>
  1. Delete import mx.controls.ComboBox; . It is no longer needed.
A Spark DropDownList is used instead of a Spark ComboBox because the Spark ComboBox items are editable by default, and the Dashboard items should not be editable. Also, notice that the DropDownList width is specified because the default behavior of the Spark DropDownList in the Dashboard does not respect the size of the largest item.
 
  1. Locate the onChangeComboBox() function and update the event type. Change ListEvent to IndexChangeEvent .
  2. At the top of the file, remove import mx.events.ListEvent; and add import spark.events.IndexChangeEvent; .
  3. Inside the onChangeComboBox() function locate the following line:
var index:Number = ComboBox(e.target).selectedIndex;
  1. Replace it with this line:
var index:Number = DropDownList(e.target).selectedIndex;
  1. Add fontFamily="verdana" to the <mx:ColumnChart> and <mx:LineChart> tags.
  2. Replace the <mx:HBox> tag with <s:HGroup> .
  3. Replace all <mx:Canvas> tags with <s:NavigatorContent> .
  4. Save your changes.

 
Changes to the PieChartContent component

In this section, you'll update the PieChartContent component.
 
  1. To begin, open PieChartContent.mxml update the namespace definitions:
xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/mx"
  1. Remember to remove the MX namespace:
xmlns:mx="http://www.adobe.com/2006/mxml"
  1. Then change the namespace prefix from mx to fx for the <mx:Script> tag and for the <mx:Component> tag.
  2. Enclose the two effects defined in the file within an <fx:Declarations> tag.
  3. Lastly, add fontFamily="verdana" to the <mx:PieChart> tag.
  4. Save your changes.

 
Changes to the FormContent component

In this section, you'll update the FormContent component. Several steps in this section are identical to steps in the section on modifying the ChartContent component.
 
  1. To begin, open FormContent.mxml and update the namespace definitions as you did for ChartContent.mxml.
  2. Update the namespace prefix for the <mx:Script> tags to fx .
  3. Add gap="7" to the <PodContentBase> root tag near the top of the file. This adds vertical space between elements in the PodContentBase container.
  4. Replace the entire MX ComboBox declaration with the following:
<s:DropDownList selectedIndex="{selectedViewIndex}" change="onChangeComboBox(event)" width="74" fontSize="10" fontWeight="bold" fontFamily="verdana"> <s:ArrayList> <fx:String>Form</fx:String> <fx:String>Grid</fx:String> </s:ArrayList> </s:DropDownList>
  1. In the onChangeComboBox() method, locate this line:
var index:Number = ComboBox(e.target).selectedIndex
  1. Replace it with this line:
var index:Number = DropDownList(e.target).selectedIndex;
  1. Change the event type in the onChangeComboBox() function from ListEvent to IndexChangeEvent .
  2. Change import mx.events.ListEvent; to import spark.events.IndexChangeEvent; .
  3. Replace all <mx:HBox> tags with <s:HGroup> tags.
  4. Remove the horizontalGap="0" property from the <s:HGroup> tag that has it.
  5. Add the gap="10" property to each <s:HGroup> tag.
  6. In the <s:HGroup> containing the newButton and deleteButton buttons, set gap="2" .
  7. Replace the <mx:VBox> tag with a <s:NavigatorContent> tag.
  8. Add the following immediately after the opening <s:NavigatorContent> tag, because it defaults to BasicLayout, and you want its children to have vertical layout:
<s:layout> <s:VerticalLayout horizontalAlign="center" gap="7"/> </s:layout>
  1. Replace the <mx:Canvas> tags with a <s:NavigatorContent> tag.
Note: Do not add the layout tag inside this instance of <s:NavigatorContent> , because in this case it is replacing a Canvas, which uses BasicLayout.
 
  1. Replace all <mx:Label> tags with <s:Label> .
Note: If you build the project now, you will see three warnings because the Spark Label control does not support data binding to its text property. You can ignore these warnings.
 
  1. Add the following to all <s:Label> tags:
fontSize="10" paddingTop="4" fontFamily="verdana"
These attributes ensure the application's Label components look like their counterparts in the Flex 3 version.
 
  1. Replace all <mx:TextInput> tags with <s:TextInput> tags.
  2. Add the following to all <s:TextInput> tags:
fontSize="10" paddingTop="4" fontFamily="verdana"
  1. Replace the <mx:TextArea> tag with a <s:TextArea> tag.
  2. Add the following to the <s:TextArea> tag:
fontSize="10" paddingTop="4" fontFamily="verdana"
  1. Replace all <mx:Button> tags with <s:Button> tags.
  2. Add fontSize="10" fontWeight="bold" fontFamily="verdana" only to <s:Button> tags that have the label property defined.
  3. Add fontSize="10" fontFamily="verdana" to the <mx:DateField> tag.
The Spark DataGrid, new to Flex 4.5, requires several changes when migrating the Dashboard application.
 
  1. Replace the <mx:DataGrid> tag with a <s:DataGrid> tag.
  2. Add fontSize="10" fontFamily="verdana" to the <s:DataGrid> tag.
  3. Change the namespace prefix for the <mx:columns> tag to s .
  4. Replace the <mx:DataGridColumn> tags with <s:GridColumn> tags.
  5. In the <s:DataGrid> tag, change the itemClick event to a gridClick event.
  6. Replace this:
itemClick="selectedIndex=DataGrid(event.currentTarget).selectedIndex;"
With this:
 
gridClick="selectedIndex=DataGrid(event.currentTarget).selectedIndex;"
  1. Change the itemDoubleClick event to a gridDoubleClick event.
  2. Replace this:
itemDoubleClick="selectedViewIndex=0;"
With this:
 
gridDoubleClick="selectedViewIndex=0;"
  1. Because the Spark DataGrid control deals with its data in a slightly different way, you need to add an <s:ArrayList> tag just after the opening <s:columns> tag, and add an </s:ArrayList> tag just before the closing </s:columns> tag.
  2. In the second <s:GridColumn> tag, change rendererIsEditor="true" to rendererIsEditable="true" .
  3. Because Spark DataGrid columns do not set their default width exactly like MX DataGrid columns, you need to add width="80" to the first and second <s:GridColumn> tags to set the initial width of the columns.
  4. In the formatDate() method, change the data type of the second parameter from DataGridColumn to GridColumn :
  5. Toward the top of the file, remove the following line as it is no longer necessary:
import mx.controls.dataGridClasses.DataGridColumn;
Next you'll create two custom button skin classes for the left and right buttons, which enable the user to move through the data items. These skins will implement the leftArrowButton and rightArrowButton styles in file styles.css.
 
  1. Create two copies of CustomMinimizeButtonSkin.mxml and rename them CustomLeftButtonSkin.mxml and CustomRightButtonSkin.mxml respectively.
  2. To use these custom skin classes in FormContent.mxml, locate the buttons that have styleName="leftArrowButton" and styleName="rightArrowButton" respectively. Remove the width , height , and styleName properties, and set the skinClass properties for the buttons as follows:
<s:Button enabled="{dataProvider.length > 0}" skinClass="skins.CustomLeftButtonSkin" click="saveData();selectedIndex-=1;"/> <s:Button enabled="{dataProvider.length > 0}" skinClass ="skins.CustomRightButtonSkin" click="saveData();selectedIndex+=1;"/>
  1. Save your changes to FormContent.mxml.
  2. Open CustomLeftButtonSkin.mxml, and replace the two BitmapImage elements with the following three tags:
<s:BitmapImage includeIn="up, down" width="9" height="12" source="@Embed(source='/assets/left_arrow_up.gif')"/> <s:BitmapImage includeIn="over" width="9" height="12" source="@Embed(source='/assets/left_arrow_over.gif')"/> <s:BitmapImage includeIn="disabled" width="9" height="12" source="@Embed(source='/assets/left_arrow_disabled.gif')"/>
  1. Open CustomRightButtonSkin.mxml, and replace the two BitmapImage elements with the following three tags:
<s:BitmapImage includeIn="up, down" width="9" height="12" source="@Embed(source='/assets/right_arrow_up.gif')"/> <s:BitmapImage includeIn="over" width="9" height="12" source="@Embed(source='/assets/right_arrow_over.gif')"/> <s:BitmapImage includeIn="disabled" width="9" height="12" source="@Embed(source='/assets/right_arrow_disabled.gif')"/>
  1. Save your changes.

 
Changes to the ListContent component

In this section you'll update the ListContent component.
 
  1. To begin, open ListContent.mxml replace the namespace definitions as you did for ChartContent.mxml.
  2. Change the namespace prefix for the <mx:Script> tag to fx .
  3. Replace import mx.controls.Label; with import spark.components.Label; .
  4. Replace <mx:List … /> with <s:List … > . (Remember to remove the slash before the closing angle bracket.)
  5. Replace borderStyle="none" with borderVisible="false" in the <s:List> tag.
  6. Add fontSize="11" in the <s:List> tag.
  7. Add a closing </s:List> tag.
  8. Add the following between the opening <s:List> tag and the closing </s:List> tag:
<s:layout> <s:VerticalLayout gap="16" paddingTop="6" paddingLeft="5"/> </s:layout>
  1. Save your changes.
Your <s:List> tag should now be similar to the following:
 
<s:List id="list" width="100%" height="100%" dataProvider="{dataProvider}" click="onClickList(event)" borderVisible="false" itemRenderer="com.esria.samples.dashboard.renderers.ListPodRenderer" fontSize="11"> <s:layout> <s:VerticalLayout gap="16" paddingTop="6" paddingLeft="5"/> </s:layout> </s:List>

 
Implementing a custom skin for the ListContent List subcomponent

The Flex 3 Dashboard ListContent component displays only a vertical scrollbar, and does not display a horizontal scrollbar. It achieves this by setting the horizontalScrollPolicy property in the custom item renderer for the ListContent List subcomponent to "off" . To remove the horizontal scrollbar in the Flex 4.5 it is necessary to create a custom skin class for the ListContent List subcomponent.
 
The custom skin will also be used to remove the border from the List control.
 
  1. Right-click the skins folder in Package Explorer and select New > MXML Skin.
  2. Type CustomListSkin for the name and select spark.components.List as the Host Component.
  3. Verify that the Create As Copy Of setting is spark.skins.spark.ListSkin, and select Remove ActionScript Styling Code.
  4. Click Finish.
  5. To use this skin class, set the skinClass property for the <s:List> tag in ListContent.mxml:
skinClass="skins.CustomListSkin"
  1. In this custom skin file, set the alpha property of the borderStroke SolidColorStroke to a value of 0 , to remove the List border:
<s:SolidColorStroke id="borderStroke" weight="1" alpha="0"/>
  1. Set the horizontalScrollPolicy property of the Scroller subcomponent in the skin class to "off" to remove the horizontal scroll bar:
<s:Scroller left="0" top="0" right="0" bottom="0" id="scroller" minViewportInset="1" hasFocusableChildren="false" horizontalScrollPolicy="off">
  1. Save your changes.

 
Changes to the ListPodRenderer component

In this section, you'll update the ListPodRenderer, which is used to render list items in the ListContent component.
 
  1. To begin, open src/com/esria/samples/dashboard/renderers/ListPodRenderer.mxml and replace the namespace definitions as you did for ChartContent.mxml.
  2. Change the namespace prefix for the <mx:Script> tag to fx .
  3. Replace <mx:HBox> with <s:ItemRenderer> .
  4. Remove the backgroundColor and horizontalScrollPolicy properties from the ItemRenderer tag, as they are not supported by the ItemRenderer class.
  5. Add the following immediately following the opening <s:ItemRenderer> tag:
<s:layout> <s:HorizontalLayout gap="12"/> </s:layout>
  1. Add the following immediately following the closing </s:layout> tag:
<s:states> <s:State name="normal"/> <s:State name="over"/> </s:states>
  1. Add the following lines to the onInitialize() function:
setStyle("rollOverColor", "#FFFFFF"); setStyle("selectionColor", "#FFFFFF");
  1. Replace <mx:Label> with <s:Label> throughout.
  2. Remove the truncateToFit="true" property from the final Label, as it is unnecessary.
  3. Add the following in the <s:Label> tags:
fontSize="10" fontFamily="verdana" kerning="off"
  1. In the nameLabel <s:Label> , replace rollOver="Label(event.currentTarget).setStyle('textDecoration', 'none');" with textDecoration.over="none" .
  2. In the same <s:Label> tag, remove this:
rollOut="Label(event.currentTarget).setStyle('textDecoration', 'underline');"
  1. Save your changes and build the project.

 
Change the URL in the news.xml data file

If you launch the Dashboard and click the links in the Company News, a new browser window opens but the page fails to load, because www.esria.com no longer exists.
 
Follow these steps to fix this:
 
  1. Open data/news.xml.
  2. Replace all occurrences of www.esria.com with www.adobe.com.
  3. Save your changes.
  4. Launch the completed application and try it out!

 
Where to go from here

That's it! You've finished porting the Adobe Flex 3 example Dashboard application to use the Flex 4.5 Spark controls and architecture.
 
It's important to note that the resulting application is not necessarily coded as it would be if you were to develop the Dashboard from scratch using Flex 4.5. Rather, the goal of the exercise was to migrate an existing application from Flex 3 to Flex 4.5, while changing as little as possible. Now that that has been achieved, you may want to look for opportunities to improve the overall quality of the Flex 4.5 Dashboard and its application architecture.
 
In fact, the best way to learn even more about the Dashboard application is to think of things it does not do, or limitations or problems you see in the Dashboard, and then try to understand and modify the code. Just remember to periodically export your project to an archive folder just in case you need to revert to an earlier version.
 
For more information on Flex 4.5—and in particular features relevant to the Dashboard application—see the following resources:
 
For more information on Flex 4.5—and in particular features relevant to the Dashboard application—see the following resources:
 
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License. Permissions beyond the scope of this license, pertaining to the examples of code included within this work are available at Adobe.
 
Note: You may use the sample code in your products, commercial or not.