Before I really get into this topic, I have to thank Adobe for opening up the Flex 2 framework. There is so much that I have learned about the inner workings of Flex by examining the framework. For those that have not looked at it, I
HIGHLY encourage you to do so. You can learn a great deal about components, containers, drawing/skinning, etc... You can download the framework from
flex.org. If you have Flex Builder installed locally on Windows, it is located at C:\Program Files\Adobe\Flex Builder 2\Flex SDK 2\frameworks\source.
On to the real meat here...
One of the key features that sets the Flex/Flash platform apart from traditional web development is that we have the drawing API. You can quickly and easily use the drawing API to programmatically draw images on the screen. You can draw a line from point A to point B to visualize data, visually separate logical groupings of information, encapsulate funcationality, etc... Adobe has done us all a huge favor by creating lots of reusable components within the Flex framework, but eventually, most Flex applications are going to look the same. Don't take this the wrong way; I'm not saying they are going to look bad. The Flex framework has a very clean look to it, and I like it. For most applications this is more than enough.
In order to set your application apart from the rest, you need to look into styling and skinning. You can use CSS styles to customize the color schemes of your application. You can use skins to completely change how a component looks, including the image and/or shape of that component. You can create skins that are images (and embed them within your application), or you can create programmatic skins. Programmatic skins are instructions to the Flash environment to use the drawing API to literally draw your component on the screen. Some great resources to get started with skinning are:
Another great place to look for skinnning reference is the Flex SDK source for the halo skin. I was inspired by Kevin Hoyt's
Accordion example from last February to look into Flex skinning some more. So I decided to make my own. Here's a screenshot of my customized accoridion skin...

I started by looking at the framework source for the halo AccordionHeaderSkin .as file. I literally copied the file to my workspace, then started chopping it up to suit my needs. Using the framwork source as a base, you can see how the color schemes are taken from the halo theme, and you can reuse them. I created a function that draws the component shape. Before I call that function, I set the line style and the gradient fill (based off of the existing code).
g.lineStyle( 1, borderColor );
g.beginGradientFill( GradientType.LINEAR, selectedFillAlphas, [1, 1], [], verticalGradientMatrix(0, 0, w, h) );
drawSkin( g, w, h, indent, inset );
g.endFill();
private function drawSkin( g: Graphics, w : Number, h : Number, indent : Number, inset : Number ) : void
{
g.moveTo( 0, indent );
g.lineTo( indent, 0 );
g.lineTo( inset, 0);
g.lineTo( inset + indent, indent/2 );
g.lineTo( w-(indent/2), indent/2 );
g.lineTo( w, indent );
g.lineTo( w, h-indent );
g.lineTo( w-indent, h-1 );
g.lineTo( w-(inset + indent), h-1 );
g.lineTo( w-(inset + indent*2), h-(indent/2)-1 );
g.lineTo( 0, h-(indent/2)-1 );
g.lineTo( 0, indent );
}
I took this same approach with the Tab navigator and panel skins also. For the Tabnavigator class, I modified the halo TabSkin.as file. For the Panel, I mofified the BorderSkin.as file. The colors all all reused from the existing halo theme, and the corners on the TabSkin reuse the cornerRadius style from the halo theme.


Once you have created you skins, you need to apply them to your application using CSS. You have to set the skin in CSS for each state that applies:
.tabSkin
{
cornerRadius: 10;
upSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
overSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
disabledSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
downSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedUpSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedDownSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedOverSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
selectedDisabledSkin: ClassReference( "com.cynergysystems.skins.TabSkin" );
}
.accordionHeaderSkin
{
upSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
disabledSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedDisabledSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
overSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
downSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedUpSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedOverSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
selectedDownSkin: ClassReference( "com.cynergysystems.skins.AccordionHeaderSkin" );
}
You can see the final result in the screenshots below. There are three screenshots: the only differences in the three are changes in the Application css definition to change the theme color and the background gradient colors:
Application
{
backgroundColor:#FFFFFF;
backgroundGradientColors: #999999, #0000FF;
backgroundGradientAlphas: 0.5, .5;
themeColor: #0000FF;
}



Feel free to contact me with any questions or comments at andrew.trice[ at ]cynergysystems.com