In this exercise, you will create a skin for the Employee Portal application and use the provided skinning components to configure the application so that it appears as shown in Figure 1. You will also learn how to create a custom skin property and reuse it to style Flex components.

Figure 1. Take stock of your tasks in this exercise.
In this exercise, you will learn how to:
In order to complete this tutorial, you need the following software and files:
In this section, you will use Flash Builder to create a skin for the Employee Portal application.
Within the Package Explorer, right-click the skins folder and select New > MXML Application (see Figure 2).

Figure 2. Create a new MXML application.
In the New MXML Application dialog box, name the application ApplicationContainerSkin (see Figure 3).

Figure 3. Name the application ApplicationContainerSkin.
Click Finish.
The ApplicationContainerSkin.mxml file will open in the Editor.
Declarations tag block.Replace the Application tags with SparkSkin tags:
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024" minHeight="768"> </s:SparkSkin>
Between the SparkSkin tags, add a Metadata tag set:
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo"
minWidth="1024" minHeight="768">
<fx:Metadata>
</fx:Metadata>
</s:SparkSkin>
Between the Metadata tags, use the HostComponent() function to assign the spark.components.Application package to the
skin:
<fx:Metadata>
[HostComponent("spark.components.Application")]
</fx:Metadata>
The HostComponent metadata tag identifies the host
component of a Spark skin class. As a result of this definition, you can access
the public members of the host component's instance from within the skin. In
other words, in this case, you can access the properties of the Application tag.
Below the Metadata tag block, add
a states tag block:
...
</fx:Metadata>
<s:states>
</s:states>
Within the states block, add a State instance with the name property value assigned to normal:
<s:states>
<s:State name="normal"/>
</s:states>
Below the State instance, add
another State instance with the name property value assigned to unused:
<s:states>
<s:State name="normal" />
<s:State name="unused" />
</s:states>
Below the states block, add a Rect tag block:
...
</s:states>
<s:Rect>
</s:Rect>
Within the opening Rect tag, assign the width property value to 973, the height property value
to 636, and the x and y property values to 0:
<s:Rect width="973" height="636" x="0" y="0">
</s:Rect>
Between the Rect tags, add stroke property block:
<s:Rect width="973" height="636" x="0" y="0">
<s:stroke>
</s:stroke>
</s:Rect>
Between the stroke tags, add a LinearGradientStroke instance with the weight property value assigned to 1:
<s:stroke>
<s:LinearGradientStroke weight="1"/>
</s:stroke>
In this section you will apply the ApplicationContainerSkin component to the Employee Portal application.
Within the opening Application tag, assign the skinClass property value to skins.ApplicationContainerSkin:
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" xmlns:s="library://ns.adobe.com/flex/spark" xmlns:mx="library://ns.adobe.com/flex/halo" width="980" height="690" xmlns:components="components.*" skinClass="skins.ApplicationContainerSkin">
You should the black outline of a rectangle (see Figure 4).

Figure 4. Run the application to see the skin applied.
In this section, you will use a Flex container control to display the Employee Portal application through the ApplicationContainerSkin skin.
Below the closing Rect tag, create a Group container and assign the id property value to contentGroup:
</s:Rect>
<s:Group id="contentGroup">
</s:Group>
Save the file and run the application.
You should see the Employee Portal application is now visible, but is not aligned properly (see Figure 5).

Figure 5. Run the application to see the skin applied.
To the Group container, assign the left property value to 20, the right property value to 10, the top property value to 25 and the bottom property value to 10.
<s:Group id="contentGroup"
left="20" right="10"
top="25" bottom="10">
</s:Group>
You should see the Employee Portal application is now centered within the skin (see Figure 6).

Figure 6. Run the application to see the EmployeePortal application is now centered in the skin.
In this section, you will apply a skin to the EmployeePortal header image.
From the Package Explorer view, open the TopContainerSkin.mxml file.
Note that the TopContainerSkin.mxml file contains code that is the same as the ApplicationContainerSkin.mxml file.
Locate the SkinnableContainer tag block.
<s:SkinnableContainer width="933" height="81"
contentBackgroundColor="0x0074aa">
...
</s:SkinnableContainer>
From the opening tag,
remove the contentBackgroundColor property value.
<s:SkinnableContainer width="933" height="81">
...
</s:SkinnableContainer>
To the SkinnableContainer tag, assign the skinClass property value to skins.TopContainerSkin:
<s:SkinnableContainer width="933" height="81"
skinClass="skins.TopContainerSkin">
...
</s:SkinnableContainer>
Save the file and run the application.
You should see the header of the Employee Portal application has a blue background (see Figure 7).

Figure 7. Apply a skin to the application header.
SkinnableContainer tags, cut the layout property tags.Group container. Between the Group container tags,
paste the layout property code that was cut in step 8:
<s:Group id="contentGroup"
verticalCenter="0"
left="20">
<s:layout>
<s:HorizontalLayout/>
</s:layout>
</s:Group>
You should see there has been no visual change committed to the application (see Figure 8).

Figure 8. Run the application to see there is no change.
In this section you will skin the application using a skin component and a CSS file.
From the Package Explorer view, open the PanelSkin.mxml file.
Note that the code is similar to the code within the ApplicationContainerSkin.mxml file you created earlier.
Panel containers.Within the selector, use
the classReference() function to assign the skinClass property value to the skin.PanelSkin component.
s|Panel
{
backgroundColor: #E8E8E8;
skinClass:ClassReference("skins.PanelSkin");
}
You should see that the panels are skinned (see Figure 9).

Figure 9. Apply a skin to the Panel containers within the application.
In this section you will learn how to use a Flash XML Graphic (FXG) file to style components in Flash Builder.
From the Package Explorer view, open the TopSkin.fxg file.
The TopSkin.fxg file was created using Adobe Illustrator CS4. The file opened in Illustrator CS4 appears as shown in Figure 10. Note that the only rounded corner is the top right corner.

Figure 10. View the TopSkin.fxg file opened in Illustrator CS4.
Path tag. From the Path tag, copy the data property and its assigned value.
<Path winding="nonZero" ai:knockout="0"
data="M0 0L0 81.2002 933.425 81.3457
933.587 13.2305C933.587 6.60303 928.214 1.23047 921.587 1.23047L774.585 1.23047
0 0Z" >
<fill>
<SolidColor color="#0684b7"/>
</fill>
</Path>
Within the file, comment
out the Rect tags and properties and uncomment the Path tags:
<!--<s:Rect radiusX="4" radiusY="4" height="100%" width="100%">
<s:fill>
<mx:SolidColor id="topContainerSkin" color="#0D86B8"/>
</s:fill>
</s:Rect>-->
<s:Path winding="nonZero">
<s:fill>
<s:SolidColor color="0x0D86B8"/>
</s:fill>
</s:Path>
Within the opening Path tag, paste the data property and value copied from the TopSkin.fxg file:
<s:Path winding="nonZero" data="M0 0L0 81.2002 933.425 81.3457
933.587 13.2305C933.587 6.60303 928.214 1.23047 921.587 1.23047L774.585 1.23047
0 0Z">
<s:fill>
<s:SolidColor color="0x0D86B8"/>
</s:fill>
</s:Path>
You should see that only the top right corner of the SkinnableContainer container skin is curved (see Figure 11).

Figure 11. Change the header skin to only have one rounded corner.
In this section, you will change the color of the title bar
for each of the Panel containers within the Employee Portal application.
HGroup container that nests the Panel containers.Between the HGroup tags, use comments to prevent the Panel container code from compiling.
<s:HGroup gap="36">
<!--<s:Panel width="287" height="472" title="Employee of the Month">
<components:EmployeeOfTheMonth/>
</s:Panel>
<s:Panel width="287" height="472" title="Cafeteria Special">
<components:Cafeteria width="100%"/>
</s:Panel>
<s:Panel width="287" height="472" title="Monthly Events">
<components:MonthlyEvents height="439" width="287"/>
</s:Panel>-->
</s:HGroup>
In the Package Explorer, right-click the components package and select New > MXML Component (see Figure 12).

Figure 12. Create a new MXML component.
In the Based on dialog
box, type Panel and select the Spark Panel container (see
Figure 13).

Figure 13. Base the new MXML component on the Spark Panel container.
In the New MXML Component dialog box, type 287 for the Height value and 472 for the Width values (see Figure 14).

Figure 14. Name the component EmployeePortalPanel, base it on the Spark Panel container, and replace the Width and Heigh valuest.
Click Finish.
The EmployePortalPanel.mxml file will open in the Flash Builder editor.
Declarations tag block.Between the Panel container tags,
create a Script block:
<s:Panel xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/halo">
<fx:Script>
<![CDATA[
]]>
</fx:Script>
</s:Panel>
Within the Script block, declare a public variable named panelTitleColor data typed to the uint class:
<fx:Script>
<![CDATA[
public var panelTitleColor:uint;
]]>
</fx:Script>
Within the HGroup that contains
the commented Panel container code, below the commented code, create an
instance of the EmployeePortalPanel component.
...
</s:Panel>-->
<components:EmployeePortalPanel>
</components:EmployeePortalPanel>
</s:HGroup>
To the EmployeePortalPanel component instance, assign the title property value to Employee of the
Month and use the code lookup tool to add the panelTitleColor property (see Figure 15).

Figure 15. Use code lookup to add the panelTitleColor property to the EmployeePortalPanel tag.
Assign the panelTitleColor property value to #64BC48 (green):
<components:EmployeePortalPanel title="Employee of the Month"
panelTitleColor="#64BC48">
</components:EmployeePortalPanel>
Within the EmployeePortalPanel component tags, add an instance of the EmployeeOfTheMonth component:
<components:EmployeePortalPanel title="Employee of the Month"
panelTitleColor="#64BC48">
<components:EmployeeOfTheMonth/>
</components:EmployeePortalPanel>
You should see only the Employee of the Month panel displayed and the panel's title color has not changed (see Figure 16).

Figure 16. Display the EmployeeOfTheMonth component using the EmployeePortalPanel component.
In this section you will create a function to handle the
passing of the panelTitleColor property value from the main application file to
the custom component.
fill property within the Path tag block. From the nested SolidColor tag, remove the color property value:
<s:fill>
<s:SolidColor/>
</s:fill>
To the SolidColor tag, assign the id property to headerSkinColor:
<s:fill>
<s:SolidColor id="headerSkinColor"/>
</s:fill>
MetaData tags. Within the HostComponent() function, change the value to reference the EmployeePortalPanel component:
<fx:Metadata>
[HostComponent("components.EmployeePortalPanel")]
</fx:Metadata>
Locate the Script comment and add a Script block below it:
<!-- Script
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -->
<fx:Script>
<![CDATA[
]]>
</fx:Script>
...
Within the Script block, create a private function named initTitleSkin that
returns a void data type:
<fx:Script>
<![CDATA[
private function initTitleSkin():void
{
}
]]>
</fx:Script>
Within the initTitleSkin() function, assign the color property of the headerSkinColor
SolidColor fill to the hostComponent.panelTitleColor property value:
private function initTitleSkin():void
{
headerSkinColor.color = hostComponent.panelTitleColor;
}
To the opening SparkSkin tag, assign
the creationComplete property value to call the initTitleSkin() function:
<s:SparkSkin xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:mx="library://ns.adobe.com/flex/halo"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="initTitleSkin()">
Save the file and run the application.
You should see the Employee of the Month panel title skin is the color green (see Figure 17).

Figure 17. Change the Employee of the Month Panel container's header color to green.
Within the HGroup container that
nests the EmployeePortalPanel component, copy the component and paste two
instances below the first:
...
<components:EmployeePortalPanel title="Employee of the Month"
panelTitleColor="#64BC48">
<components:EmployeeOfTheMonth/>
</components:EmployeePortalPanel>
<components:EmployeePortalPanel title="Employee of the Month"
panelTitleColor="#64BC48">
<components:EmployeeOfTheMonth/>
</components:EmployeePortalPanel>
<components:EmployeePortalPanel title="Employee of the Month"
panelTitleColor="#64BC48">
<components:EmployeeOfTheMonth/>
</components:EmployeePortalPanel>
</s:HGroup>
To the second instance of the EmployeePortalPanel component, reassign the title property to Cafeteria Special, the panelTitleColor property value to #F05123 (orange) and change the nested
component to the Cafeteria component.
<components:EmployeePortalPanel title="Cafeteria Special"
panelTitleColor="#F05123">
<components:Cafeteria/>
</components:EmployeePortalPanel>
To the third instance of the EmployeePortalPanel component, reassign the title property to Monthly Events, the panelTitleColor property value to #0D86B8 (blue) and change the nested
component to the MonthlyEvents component.
<components:EmployeePortalPanel title="Monthly Events"
panelTitleColor="#0D86B8">
<components:MonthlyEvents/>
</components:EmployeePortalPanel>
You should see the three panels have different colored headers (see Figure 18).

Figure 18. Pass the EmployeePortalPanel component the header color from the main application.
HostComponent metadata tag used for within a skin?HostComponent metadata tag identifies the host component of a Spark skin class and allows you to access the public members of the host component’s instance from within the skin.Group container with an id of contentGroup in the skin?Group container with an id of contentGroup in the skin displays the complete content of the skin.classReference() function to assign the skinClass property value to the component being skinned.Trilemetry, Inc is a development and education organization that implements a human-centered design approach to the creation of software and content. Their Adobe portfolio includes the Adobe ColdFusion Getting Started Experience, the Adobe Flex Getting Started Experience, the Flex in a Week video series, the official Adobe instructor-led training course Flex 3: Extending and Styling Components and more. They also create and support many Web applications from interactive Flash sites and corporate web sites to mission-critical business applications.