FlashPlatformist
Articles, Information, News, & Tutorials for Adobe Flash Platform Developers and Architects

Building Custom Components with Flex 4

Upon conducting the necessary research for my current chapter in Flex 4 in Action that I am working on, I felt it would be worthwhile to post a blog to help clarify some confusion that may be surrounding the Flex 3 versus Flex 4 components. Contrary to my previous post, I’m not speaking from an architectural standpoint, but a simple “what is and what isn’t” checklist to hopefully help save you some time as you learn the Flex 4 SDK.

Where do Spark Components come from?

A Flex 4 Spark component is simply an extension of the Flex 3 (Halo)UIComponent base class. Additional classes are stacked on top of UIComponent primarily to separate the presentation layer from the business layer. This is primarily accomplished with the Group and SkinnableComponent classes in the Spark library. These classes are hooks into the extended functionality of the Flex 4 Spark library, while still keeping that of the Flex 3 Halo libarary. You may be asking yourself at this point – how does one get the best of both worlds then?

The Group and SkinnableComponent classes both extend the UIComponent base classs. If you are familiar with Flex 3, then I certainly hope you are familiar with the UIComponent class. If not, I suggest reading up on it before going any further with any Flex development.

As you might expect, most of the viewable components in the Spark library extend either the Group or SkinnableComponent class. The only difference between the two is that Group is used to improve performance and minimize application size because it does not include the added weight of skinning. Therefore, if you are building a component that does not require skinning, then use Group as your base class. If you want your component to be skinnable via a separate Skin class, extend one of the base classes that are derived from SkinnableComponent.

Example Scenarios

For example, if you are building a composite container component to hold a series of unrelated display objects, extend the SkinnableContainer class. This gives you the ability to attach a separate Skin class to the container, which could be straight FXG exported from Flash Catalyst that a designer may have given you for the component.

Another example might be if you are building a custom component that will hold data in the form of item renderers. In this case, you should extend the SkinnableDataContainer class, or even the Spark ListBase class. However, a component like the Flex 4 VideoPlayer is built directly from the SkinnableComponent class instead of SkinnableContainer. Which class you should use is ultimately a judgement call based on how lightweight you need the component to be.

Of course, the more you get to know the code inside the Spark library classes, the easier it will be to figure out which class you should extend when building custom Flex 4 components.

Possibly Related Posts:



Posted by Dan Orlando on June 28th, 2009 :: Filed under Tutorials

Understanding the Flex 4 Spark Component Architecture and how to Build Custom Components with the Flex 4 SDK

The architecture of the new Spark components in Flex 4 supercedes the Halo components of Flex 3. Upon learning how to leverage the  architecture of Spark components, you will find the improvements to be quite substantial.

Ultimately, the new component architecture with the Spark library makes building, modifying, and designing custom components a lot easier and far more intuitive. The most significant architectural changes are internal state management and decoupled visual appearance.

Internal State Management

The declaration of global application states is still possible, but the trick to getting a Flex application to closely resemble a native desktop application is by changing the state of individual container components while holding the state of others. This is what gives the application a “seamless” flow. This is accomplished by creating multiple skins for a single component, and just swap them out in an event handler. The code for the skin itself should have the following structure:

<Skin xmlns="http://ns.adobe.com/mxml/2009">

    <states>
        <State name="up" />
        <State name="over" />
        <State name="down" />
        <State name="disabled" />
    </states>

    ...
</Skin>

In the example above, state changes are controlled by the component, as the component class is responsible for internal behaviors. However, a single state change could include the attachment of a new skin class.   In addition to controlling it’s currentState property, the component broadcasts this value to its parent through the use of meta data. That means the parent can still override the built-in states of a component, and most importantly, the parent application is able to easily find out the current state of any of its children.

Decoupled Visual Appearance

HOWEVER, skin states are not the same as component states. A component state can change without the skin state changing. In other words, component states are decoupled from skin states. Component states define changes to the behavioral state of a component, while Skin states define changes to the display state of the component that they are attached to. For example, the Button class has a set of states that include: up, down, selected, and disabled. The Button drives state changes to ButtonSkin, which is the skin that is attached to the Button component. The Button and ButtonSkin classes both have their own currentState property, which is accessible by the parent container. This is a good example of the Template design pattern.

The following code sample is taken from ButtonSkin.mxml and provides a nice depiction of what we are talking about here:

<?xml version="1.0" encoding="utf-8"?>
<Skin xmlns="http://ns.adobe.com/mxml/2009">

    <Metadata>
        [HostComponent("spark.components.Button")]
    </Metadata> 

    <states>
        <State name="up" />
        <State name="over" />
        <State name="down" />
        <State name="disabled" />
    </states>

    <!-- border -->
    <Rect left="0" right="0" top="0" bottom="0" minWidth="70" minHeight="24">
        <stroke>
        <SolidColorStroke color="0x808080" color.disabled="0xC0C0C0" />
        </stroke>
    </Rect>

    <!-- fill -->
    <Rect left="1" right="1" top="1" bottom="1" minWidth="68" minHeight="22">
        <stroke>
        <SolidColorStroke color="0xFFFFFF" color.over="0xFAFAFA" color.down="0xEFEFEF" />
        </stroke>
        <fill>
        <SolidColor color="0xFFFFFF" color.over="0xF2F2F2" color.down="0xD8D8D8" />
        </fill>
    </Rect>

    <!-- label -->
    <TextBox text="{hostComponent.label}"
         fontFamily="Arial" fontSize="11"
         color="0x444444" color.disabled="0xC0C0C0"
         horizontalCenter="0" verticalCenter="0"
         left="10" right="10" top="4" bottom="2"
         textAlign="center" verticalAlign="middle">
    </TextBox>

</Skin>

Now that you have reviewed the code for the default Spark skin class that is used by the <code>Button</code> component, let’s take a look at the code for the <code>Button</code> component in the Spark library:

package spark.components {
/**
 *  Up State of the Button
 */
[SkinState("up")]
/**
 *  Over State of the Button
 */
[SkinState("over")]
/**
 *  Down State of the Button
 */
[SkinState("down")]
/**
 *  Disabled State of the Button
 */
[SkinState("disabled")]
public class Button extends SkinnableComponent implements IFocusManagerComponent {  

    /**
     *  @return Returns true when the mouse cursor is over the button.
     */
    public function get isHoveredOver():Boolean {
        return flags.isSet(isHoveredOverFlag);
    }

    /**
     *  Sets the flag indicating whether the mouse cursor
     *  is over the button.
     */
    protected function setHoveredOver(value:Boolean):void {
        if (!flags.update(isHoveredOverFlag, value))
            return;

        invalidateSkinState();
    }

    // GetState returns a string representation of the component's state as
    // a combination of some of its public properties
    protected override function getUpdatedSkinState():String
    {
        if (!isEnabled)
            return "disabled";

        if (isDown())
            return "down";

        if (isHoveredOver || isMouseCaptured )
            return "over";

        return "up";
    }

    //--------------------------------------------------------------------------
    //
    //  Event handling
    //
    //--------------------------------------------------------------------------

    protected function mouseEventHandler(event:Event):void
    {
        var mouseEvent:MouseEvent = event as MouseEvent;
        switch (event.type)
        {
            case MouseEvent.ROLL_OVER:
            {
                // if the user rolls over while holding the mouse button
                if (mouseEvent.buttonDown && !isMouseCaptured)
                    return;
                    setHoveredOver(true);
                break;
            }

            case MouseEvent.ROLL_OUT:
            {
                setHoveredOver(false);
                break;
            }

        }
    }
}

}

As you can see in the third code listing, a SkinState meta data declaration is used to define the states of the attached skin. To change skin states, you should use invalidateSkinState() and getCurrentSkinState(). The invalidateSkinState() method is what invalidates the skin state, and sets the skin’s state to that which is returned by the getCurrentSkinState() method. The getCurrentSkinState() method keeps track of any internal properties on the component and figures out what state the skin should be in.

This may seem a bit complicated at first, but as you begin to develop your own custom Flex 4 components, it will quickly become apparent that this is a very valuable architectural change to components for this new iteration.

Possibly Related Posts:



Posted by Dan Orlando on June 13th, 2009 :: Filed under Tutorials
Tags :: , ,

Adobe Flash Builder 4: Data-centric Features for PHP (PHPBuilder.com)

I just ran across an article I wrote during the Flash Builder 4 beta pre-release, which was apparently published today (of course, no one tells me these things, which is ironic). It discusses the new Data-centric features for PHP built into Flash Builder 4.

Coming from a PHP background, my goal was to help accelerate the learning curve involved with getting to know the powerful new RIA tools into your development workflow. It is really worth learning how to utilize these new features, I guarantee it will speed up your workflow ten-fold once you get the hang of using them.  So check it out!

PHPBuilder.com - Adobe Flash Builder 4: Data-centric Features for PHP

PHPBuilder.com - Adobe Flash Builder 4: Data-centric Features for PHP

Possibly Related Posts:



Posted by Dan Orlando on June 9th, 2009 :: Filed under Announcements, Flash Platform News
Tags :: , , ,

Data-centric Adobe Flash Builder development with the Zend Framework

The first of a series of articles I recently wrote on the Data-centric features of Flash Builder 4 was recently published on the Zend Developer Zone. Obviously this article focuses on the built-in automated data-centric development features for PHP and the Zend framework in Flash Builder 4 beta. Check it out.

Data-centric Adobe Flash Builder development with the Zend Framework

Data-centric Adobe Flash Builder development with the Zend Framework

Possibly Related Posts:



Posted by Dan Orlando on June 4th, 2009 :: Filed under Announcements, Flash Platform News, Tools & Innovation
Tags :: , , ,

Designing (RED)Wire, Part 3: Advanced Styling Methods for Enhanced User Experience with Adobe Flex and AIR

Introduction

In the last segment, you learned how to leverage CSS to style components for large-scale Flex and AIR applications. In part three of this series, you will discover how to style application components programmatically.

The 3D interactive menu state of the application required some programmatic styling in order to lay out the 3D planes properly in their respective positions

The 3D interactive menu required some programmatic styling in order to position the 3D planes properly

Using the getStyle() and setStyle() Methods

All components derived from the UIComponent base class inherit two methods, called getStyle() and setStyle(). These two methods provide an incredible amount of flexibility to the developer, especially for programmatic skinning. Although covering all the possible uses of this functionality is beyond the scope of this article, I will show you a couple of different uses of it to demonstrate the power behind this functionality, as follows:

private function toMinimized():void {
	   TaskBarManager.addToTaskBar(this);
	   pushStateProperties(stateMin, x, y, 200, titleBar.height, NaN, NaN);

	   minimizeButton.setStyle("upSkin", getStyle("restoreButtonUpSkin"));
	   minimizeButton.setStyle("disabledSkin", getStyle("restoreButtonDisabledSkin"));
	   minimizeButton.setStyle("downSkin", getStyle("restoreButtonDownSkin"));
	   minimizeButton.setStyle("OverSkin", getStyle("restoreButtonOverSkin"));

	   maximizeButton.setStyle("upSkin", getStyle("maximizeButtonUpSkin"));
	   maximizeButton.setStyle("disabledSkin", getStyle("maximizeButtonDisabledSkin"));
	   maximizeButton.setStyle("downSkin", getStyle("maximizeButtonDownSkin"));
	   maximizeButton.setStyle("OverSkin", getStyle("maximizeButtonOverSkin"));

	   dispatchEvent(new Event("minimize"));
}

The toMinimized method seen in the code listing above is taken from a custom component that extends the Flex Panel class, and gives the appearance of a new window within the application that can be minimized so that only the title bar is showing in case the user has to access something that is behind it. The cool thing about it, is that when the window is in the minimized state, the minimize button is re-skinned on the fly using the setStyle method, which turns the button into a “restore” button, and the new state for the maximize button skin is also set. Essentially, we are reusing the same instance of a class by using it as a toggle button programmatically. Here is another example, this time using MXML:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="absolute"
	creationComplete="init()">

	<mx:states>
		<mx:State name="MyLibraryState">
			<mx:AddChild position="firstChild">
				<comp:CollectionsLibrary height="100%" width="100%"
					horizontalCenter="0" verticalCenter="0">
				</comp:CollectionsLibrary>
			</mx:AddChild>
			<mx:SetStyle name="backgroundImage"
				value="@Embed(source='com/assets/my_collections_background.png')" />
			<mx:SetProperty target="{vbox1}" name="y" value="442.95"/>
		</mx:State>
	</mx:states>
	(…)

The setStyle method is also conveniently available to the developer through MXML using the syntax: . The code listing above sets a new background image when the state of the application is changed.

Compiling Style Sheets to Load at Runtime

An interesting feature in Flex 3 is that a CSS file can be compiled as a SWF and loaded at runtime. Using this feature, you could allow the user to change the look and feel of your application based on their own personal preference. You may have seen this type of functionality used on social media web sites, where JavaScript is used to swap CSS files when the user selects a new design view.

Not surprisingly, accomplishing this is very easy in Flex. Simply create a new CSS file, place your CSS style selectors in it, and save the file. Then, in the Flex navigator panel (upper left panel when in “Flex Development” mode), right click the CSS file you just created and select the option “Compile CSS to SWF”.

The CSS for the 3D interactive menu was loaded at runtime to layout the 3D planes. In this instance, the CSS information was loaded from a local database and parsed using a custom CSS parser class.

The CSS for the 3D interactive menu was loaded at runtime to layout the 3D planes. In this instance, the CSS information was loaded from a local database and parsed using a CSS parser/helper class

The StyleManager class

After you have created and compiled all of the CSS style sheets that you want to use in your application to separate SWF files, the Flex StyleManager class can be used to easily switch between style sheets, as demonstrated in the following code listing:

private function loadFirstStyleSheet():void {
	StyleManager.loadStyleDeclarations("CSS1.swf");
}

private function loadSecondStyleSheet():void {
	StyleManager.loadStyleDeclarations("CSS2.swf");
}

Computational Expense

One very important thing to take into consideration when loading precompiled style sheets at runtime is the load that you are putting on the user’s system as a result. This method of design implementation should be used conservatively and with extreme caution, as doing a lot of it will quickly degrade the performance of your application due to a lack of available system resources.

Conclusion

In this article series, you have seen a number of methods and techniques for implementing CSS in large-scale Flex applications. Interestingly, the Flash Platform has evolved so much in the last six months, that this article series barely scratches the surface. User Experience Design is taken to the next level with the proliferation of Flash Catalyst and Flash Builder, both of which will be in public beta in a matter of days. Additionally, the Flex 4 SDK expands on the already powerful capabilities of CSS within Flex, making the Flash Platform even more lucrative for RIA development and the number one choice for providing the best possible User Experiences.

Possibly Related Posts:



Posted by Dan Orlando on June 1st, 2009 :: Filed under General, User Experience
Tags :: , ,