You are currently browsing the category archive for the 'Flex' category.

Following up my post last week on creating channel definitions, I realize I forgot to add one key piece of code - timeouts!

Why are these important?

For starters, the connection timeout prevents you from waiting until the end of time to get a response from the remote destination. Since you typically connect when your application first loads, this can result in an unnaturally long startup time when the remote destination is slow or unavailable.

Not having a connection timeout also causes failover (e.g. from RTMP to polling) to take a really long time.

Similarly, the request timeout helps prevent your application from appearing unresponsive. Better to handle slow asychronous calls with progress indicators rather than simply hope they’ll return in a reasonable amount of time.

So without further ado, here are the lines to add to your channel definitions for connection and request timeouts:

// sets the connection and request timeouts
var connectTimeoutInSec : Number = 3;
var requestTimeoutInSec : Number = 10;

rtmpChannel.connectTimeout = connectTimeoutInSec;
rtmpChannel.requestTimeout = requestTimeoutInSec;

pollingChannel.connectTimeout = connectTimeoutInSec;
pollingChannel.requestTimeout = requestTimeoutInSec;


The actual values are arbitrary, so you should adjust them as needed.

Original post: Creating FDS Channel Definitions in AS3

Anyone familiar with Flex Data Services knows about services-config.xml.

This file usually contains security constraint definitions, channel definitions, and logging settings that each of the services can use. (more here)

It’s one of those config files that always feels more complicated than it needs to be, and to top it off, it’s a compile-time resource. This limits its flexibility, especially when it comes to channel definitions.

Why should you have to recompile your application whenever your channel definitions change? Let’s declare them in AS3 instead!

Here’s an example of two channel definitions from a services-config.xml file:

<channel-definition id=”cf-polling-amf”
    class=”mx.messaging.channels.AMFChannel”>

    <endpoint uri=”http://{server.name}:80/flex2gateway/cfamfpolling”
        class=”flex.messaging.endpoints.AMFEndpoint”/>

    <properties>
        <polling-enabled>true</polling-enabled>
        <polling-interval-seconds>2</polling-interval-seconds>
    </properties>

</channel-definition>

<channel-definition id=”cf-rtmp”
    class=”mx.messaging.channels.RTMPChannel”>

    <endpoint uri=”rtmp://{server.name}:2048″
        class=”flex.messaging.endpoints.RTMPEndpoint”/>

</channel-definition>


Now let’s look at the same two channel definitions in AS3:

var serverName : String = parameters.serverName;

var pollingChannel : AMFChannel = new AMFChannel (”cf-polling-amf”,
    ”http://” + serverName + “:80/flex2gateway/cfamfpolling”);
var rtmpChannel : RTMPChannel = new RTMPChannel (”cf-rtmp”,
    ”rtmp://” + serverName + “:2048″);

pollingChannel.pollingEnabled = true;
pollingChannel.pollingInterval = 2000;

var channelSet : ChannelSet = new ChannelSet ();
channelSet.addChannel (pollingChannel);
channelSet.addChannel (rtmpChannel);


At first glance this code doesn’t appear to offer any advantage over the channels defined in services-config.xml. However in the AS3 code, the server name for the channels is passed in as a flashVar to the application.

This allows your application to determine at runtime which channels to use, and it also eliminates the need to compile the XML file into your application.

Two wins in my book.

Addendum: Adding Channel Definition Timeouts

LiveCycle Data Services. I’ve mentioned it before.

It can be an indispensable tool. But like any good black box, getting it to work properly is a huge pain in the ass.

One of the biggest benefits of LCDS is paging. Paging lets you dynamically load data as soon as it’s accessed within a collection. This is great for large data sets, and the beauty of this approach is that you don’t have to do anything special for it to work.

Create a collection, bind it to your view, and connect it to a data service. As you interact with the view, LCDS will automatically retrieve the data in the background.

Beautiful, right?

But let’s say you want to use a custom component instead of a standard List or DataGrid to display your data. This is where the magic breaks down.

You see, LCSD only works “as advertised” when you use built-in components. Any Flex component that can accept an ICollectionView as a dataProvider has specific logic to handling paging.

This is because paging is just a series of asynchronous remoting calls performed behind the scenes. When a component tries to access data that isn’t available, an ItemPendingError is thrown and a remoting call is made to retrieve it.

Since there’s nothing to access right away, the component will substitute a placeholder in lieu of the actual data. When the remoting call returns, the component will then swap out the placeholder for the data.

This is all fine and good, even though it does reveal somewhat how the sausage is being made. You just don’t get any of this for free if you use your own custom component.

However this doesn’t mean it’s impossible. You just have to support the asynchronous method in which the data is accessed - something I’ll detail in a future post.

(cliffhanger) :-)

Caching images in your Flex application can greatly improve performance and reduce the overhead of loading external resources.

And I’m not simply talking about using the cacheAsBitmap property to improve rendering performance or the cachePolicy property to speed up animations. I’m talking about caching the actual bitmap data of an image.

To get started, you’ll need a hash map to store the image data. A Dictionary or an associative array will also work just fine.

Loading an image for the first time is the same as usual. You create a new Image object and add a listener for the COMPLETE event:

var image : Image = new Image ();
image.addEventListener (Event.COMPLETE, onImageComplete);


Once the image has finished loading, you add a copy of the bitmap data to the hash map using the image URL as the hash key:

private function onImageComplete (event : Event) : void
{
    var image : Image = event.target as Image;

    if (! imageCache.containsKey (image.source))
    {
        var bitmapData : BitmapData = new BitmapData
            (image.content.width, image.content.height, true);

        bitmapData.draw (image.content);

        imageCache.put (image.source, bitmapData);
    }
}


Now we can use the image as many times as we want without ever having to load it again!

To take advantage of this, you’ll need to check the hash map every time you create a new image (or change the source property) to see if you’ve already cached it:

var image : Image = new Image ();
image.addEventListener (Event.COMPLETE, onImageComplete);

if (imageCache.containsKey (imageURL))
{
    image.source = new Bitmap (imageCache.getValue (imageURL));
}
else
{
    image.source = imageURL;
}


And that’s it!

If you have an application that loads a large number of images you may want to limit the number of cached images to prevent the Flash player memory usage from getting out of hand, but in general caching even several dozen large images only results in a slightly increased footprint.

A simple way to track memory usage in your Flex application is to create a Label that displays the System.totalMemory property and updates it on render events.

This isn’t anything fancy, but it’s useful when checking for memory leaks and helps you avoid making mistakes when dealing with memory intensive applications.

Also, its just kind of cool. 8-)

You can even go a step further and create a button that allows you to manually perform garbage collection. This, coupled with the memory monitor, gives you the basic workings of a Flash Player memory management tool.

Just remember that System.totalMemory reports the total memory in use across ALL instances of Flash Player and not just the current one - so if you have other Flash or Flex applications open your usage patterns will be skewed!

Here’s some sample code for the label and button:

<mx:Label id=”totalMemory”
    text=”{(System.totalMemory / 1024) + ‘ KB’}”
    render=”totalMemory.text = (System.totalMemory / 1024) + ‘ KB’” />

<mx:Button id=”gcButton”
    label=”force garbage collection”
    click=”System.gc ()” />

It seems that Flex Builder 3 has an issue when it comes to reseting warnings about non-bindable properties.

Consider the following example:

<?xml version=”1.0″ encoding=”utf-8″?>
<mx:Application
    xmlns:mx=”http://www.adobe.com/2006/mxml”>

    <mx:Script>
        <![CDATA[

            [Bindable] public var model : Model;

        ]]>
    </mx:Script>

    <mx:Canvas height=”{model.newHeight}” />

</mx:Application>


package
{
    public class Model
    {
        public var newHeight : Number;
    }
}


As you can see, the MXML file is data-binding the height property in the Canvas container to the newHeight property in the model.

If you compile this application, you should expect to receive the following warning:

Data binding will not be able to detect assignments to “newHeight”

To resolve this, you just need to make the newHeight property bindable. No big deal.

However if you make this change and recompile the application, the warning about the property will not disappear.

It seems that the compiler is not so smart when it comes to bindable property changes. If you go back and edit the MXML file, or clean the project and recompile, the warning will disappear.

While this is nothing more than an annoyance, it’s always good to know that’s it’s not a problem with your code. :-)

Adding a transition effect to a component is a great way to provide a subtle yet distinctive feel in your application.

For example, adding a Fade as the rollOverEffect for a component so it gradually fades in when the user moves the mouse over the component.

However this method is not without its faults.

Say you want to add a Fade as the rollOutEffect for the same component so it gradually fades out when the user moves the mouse away from the component.

This will work fine, until the Fade effects come into contact with one another.

The problem is if the rollOutEffect fires before the rollOverEffect finishes (or vice-versa) Flex will end the unfinished effect and play the new one. The result is a jagged transition.

Luckily, this is something we can easily correct.

First step? Ignore rollOverEffect and rollOutEffect. They aren’t doing us any good. Define custom event handlers for rollOver and rollOut instead.

Next, configure your Fade effects to work together. Instead of adjusting the alpha from min to max (roll over) and max to min (roll out), adjust it from the current value to max and the current value to min.

While seemingly innocuous, this is the key to a smooth transition.

The last step is to check if the effects are already playing in your event handlers. In the roll out event handler, check if the fade in effect is playing and if so, stop it before playing the fade out effect. Implement the roll over event handler in a similar manner.

In the end you should end up with something like this:

<mx:Fade id=”fadeIn
    duration=”100” startDelay=”0
    alphaFrom=”{this.alpha}” alphaTo=”1.0 />

<mx:Fade id=”fadeOut
    duration=”100” startDelay=”0
    alphaFrom=”{this.alpha}” alphaTo=”0.3 />

<mx:Script>
    <![CDATA[
        private function onRollOver (event : MouseEvent) : void
        {
            if (fadeOut.isPlaying)
            {
                fadeOut.stop ();
            }

            fadeIn.play ([this]);
        }

        private function onRollOut (event : MouseEvent) : void
        {
            if (fadeIn.isPlaying)
            {
                fadeIn.stop ();
            }

            fadeOut.play ([this]);
        }
    ]]>
</mx:Script>


Since these transitions take the current state into consideration, they will always smoothly animate from the current state to their target state.

And that, my friends, is how we do it in the NBA.

Smoothing is not enabled by default on standard Flex Image controls.

While this doesn’t affect the quality of images displayed at their native resolution, it does reduce the quality of scaled images.

To resolve this, I created a custom control that enables smoothing by default:

package
{
    import flash.display.Bitmap;
    import mx.controls.Image;

    public class SmoothImage extends Image
    {
        override protected function updateDisplayList
            (w : Number, h : Number) : void
        {
            super.updateDisplayList (w, h);

            // checks if the image is a bitmap
            if (content is Bitmap)
            {
                var bitmap : Bitmap = content as Bitmap;

                if (bitmap != null &&
                    bitmap.smoothing == false)
                {
                    bitmap.smoothing = true;
                }
            }
        }

    }
}


You can download this control from the entry I posted to the Flex cookbook:
http://www.adobe.com/cfusion/communityengine/index.cfm?event=showdetails&productId=2&postId=9409&loc=en_US

You’d think adding a Sprite to a Flex component would be easy, right?

Sprites extend DisplayObject, and the addChild() and addChildAt() methods for every Flex component take in an object of type DisplayObject.

Not quite.

From the Adobe® Flex® 3 Language Reference (emphasis added):

Note: While the child argument to the method is specified as of type DisplayObject, the argument must implement the IUIComponent interface to be added as a child of a container. All Flex components implement this interface.

To add a Sprite to a Flex component, you’d have to extend Sprite and implement IUIComponent, which frankly is more effort than its worth.

A far easier solution is to create a custom class that extends UIComponent and acts as a wrapper for the Sprite.

The constructor for such a class would look something like this:

public function SpriteUIComponent (sprite : Sprite)
{
    super ();

    explicitHeight = sprite.height;
    explicitWidth = sprite.width;

    addChild (sprite);
}


Using this custom class, you would add a Sprite to a Flex component like so:

myContainer.addChild (new SpriteUIComponent (mySprite));

Easy.

When you display formatted text in a single control like TextArea or TextInput the control handles text alignment automatically.

However if you have formatted text split across several controls it may not align properly until you adjust the baseline position of the formatted text.

Take a look at the two screenshots below. The one on the left shows two UITextField controls with formatted text that have different font sizes. The one on the right shows the same two controls with their baseline positions adjusted.

It’s important to note that adjusting the height of each control is not the same as adjusting the baseline position.

To align the “subtitle” text with the “Title” text like in the screenshot above, you would do something like the following:

subtitle.y += Title.baselinePosition - subtitle.baselinePosition;

If you have more two components with formatted text, simply record the largest baseline position and add the difference to the vertical position of each component.

This library allows you to programmatically create TinyURLs in your Flex or Flash application. It contains exactly one class with exactly one static function:

TinyURL.create (url : String, callback : Function) : void

The premise is simple - pass in a URL, and get back a TinyURL in your callback method. Callback methods have the following signature:

function callback (tinyURL : String) : void

I toyed around with having the create() method return the TinyURL directly, but that didn’t work out very well given the fact it’s an asynchronous operation.

Still, I’m happy with how it turned out. I wrote this library mostly because I wanted to see if I could, and I thought it would be cool. And I did. (and it is) :-)

Click here to view the application demo (source included)

Click here to download TinyURL Flex Library

When I write Flex applications I often encapsulate the user interface in a single container so the main MXML file isn’t muddled with both startup logic and UI components.

This also has the benefit of reducing the layout complexity. Since there’s only a single container to worry about, it can always have 100% height and width.

With absolute positioning, the container is placed at (x=0, y=0). With vertical or horizontal positioning, the vertical and horizontal alignments are set to middle and center, respectively.

Either way you end up with a single container in the center of your application taking up 100% of the width and 100% of the height - no difference, right?

Not quite.

Check out the following two screenshots. The one on the left uses absolute positioning. The one on the right uses vertical positioning.

See the difference?

It turns out that vertical and horizontal positioning result in a rather sizable margin around your container. Setting the vertical and horizontal gaps to zero have no effect.

Absolute positioning results in the appearance you would expect - the container taking up the entire application space.

While it’s not hard to modify the vertical positioning code to produce the same result as absolute positioning, why bother? :)

There’s a difference between the URL your Flex application’s SWF file was loaded from and the URL your Flex application’s SWF file is actually running from.

The former is easy to retrieve via the read-only property Application.application.url.

The latter is (slightly) more complicated. Although Flex does not provide the built-in ability to determine the URL your Flex application is running from, our good friend JavaScript is happy to lend a helping hand.

Using ExternalInterface, you can call “window.location.href.toString” to retrieve the URL your Flex application is running from.

Although there are many different permutations to retrieve this URL using window.location, I prefer the above method because it also returns any query parameters passed into the URL.

I created a static class called JSUtil so I could quickly access this method in my code, the source of which you can view here.

Update: Code snippets I’ve posted using Private Paste are randomly disappearing, so if the above link no longer exists, here’s a backup.

Adobe has a great article over at the Flex Developer Center on how to add drag-and-drop support to your Flex application:

http://www.adobe.com/devnet/flex/quickstart/adding_drag_and_drop/

This article provides a great foundation for developers who want to learn how drag-and-drop works inside Flex.

However all their examples use what’s called a “drag proxy” for their drag operations, which is pretty weak if you want a true drag-and-drop look-and-feel in your application.

The problem with using a drag proxy is that the object being dragged looks like it’s being copied instead of dragged. The original object is only moved after the drag operation is complete.

That may be good enough for some applications, but when you want your objects to look like they’re being moved in real-time, this “copy effect” just doesn’t cut it.

So let’s take a look at what goes into a drag operation.

The first parameter in the DragManager.doDrag() method is the dragInitiator. This is the component that started the drag operation.

As it turns out, the dragInitiator is all you need to improve the look-and-feel of your drag operations.

If you pass the dragInitiator in as the dragImage for your drag operation, the DragManager will drag the component directly!

How’s that for simple?

Anyone who’s designed a Flex application built on LiveCycle Data Services knows the love-hate relationship that comes with it.

But regardless of the effort, no one can deny that managed collections kick some serious ass. With paging enabled, you can access datasets with hundreds of thousands of items one page-at-a-time, thereby reducing server load and avoiding a UI-rendering black hole.

However, this comes at a price. You no longer have immediate access to all of the data in your collection, although it certainly seems like you do. Iterate through the collection once, and you’ve ruined all the benefits paging was designed to offer you.

LCDS Tip #1: NEVER iterate through a managed collection!

How does this affect sorts and filters applied to your collection? The Flex implementations of ICollectionView retrieve all the items from a destination before executing a sort or filter.

That’s the rub. Apply a sort or filter to your collection, and paging is out the door. Which kind of defeats the purpose of using LCDS to begin with.

Or does it?

You could of course include the sort or filter criteria in the signature for your destination, but even that’s an unnecessary step. If you simply apply a sort or filter BEFORE you perform the fill, LCDS will know what you’re trying to do and will happily return paged data that is sorted and/or filtered.

How’s that for awesome?

So long as you don’t need to change the sort or filter criteria after the fill, you’re in the clear. And if you do have a variable sort or filter you can, like I mentioned above, simply release your collection, re-apply the sort or filter, and then perform the fill again.

I knew I loved LCDS. ;-)

One of my biggest pet-peeves in Flex is the apparent lack of tweening support for device fonts.

Let’s say you have a container with a couple of text components, and the text components are all using device fonts. If you try to apply a Fade effect, for example, to animate the alpha property of the container from opaque to transparent, the text will not animate.

This leaves you with a couple of text components that appear to have broken free from the confines of their container. This is anarchy.

So how do we apply tweening effects to text components using device fonts? Apply filters to them.

Let’s return to the example above. If you apply a filter to each of the text components (such as a BlurFilter) before you apply the Fade effect, the device fonts will animate beautifully with the rest of the container.

myLabel.filters = [new BlurFilter ()];

Once your effect is complete, you can remove the filter (if necessary).

myLabel.filters = [];

It’s that easy.

Let’s be honest: localizing the UI text in an application is pretty easy.

Add all the strings you plan to display to a properties file or a value object and simply reference them in your UI components.

But what about the components that have information known only at runtime, such as a username or the current date? How should they be handled?

There are two ways. The first way is stupid and complicated. The second is completely awesome. Let’s start with the stupid way:

1) Create strings for each static segment of a dynamic piece of text

For example, if you wanted to display a simple greeting in your application, such as “Hi [some user] ! Welcome to [some application] !” it would look like this:

public var greeting1 : String = "Hi ";
public var greeting2 : String = "! Welcome to ";
public var greeting3 : String = "!";
<mx:Label text="{greeting1 + username + greeting2 + appName + greeting3}" />

Gross, isn’t it?

This brings us to the better (and totally awesome) way:

2) Use regular expressions to replace dynamic information at runtime

Let’s look at the same example using regular expressions:

public static const USERNAME_PATTERN : RegExp = /USERNAME/;
public static const APP_NAME_PATTERN : RegExp = /APP_NAME/;
public var greeting : String = "Hi USERNAME! Welcome to APP_NAME!";
<mx:Label text="{greeting.replace (APP_NAME_PATTERN, appName).replace (USERNAME_PATTERN, username)}" />

Isn’t that beautiful?

Although using regular expressions involves creating a RegExp pattern for each piece of dynamic information, the benefit is that the locale data can be changed without having to recompile the application.

For example, say you wanted to change the simple greeting to something like: “Welcome to [some application], [some user] !”.

Using text segments, you would not only have to change the locale data, you would have to reorder the variables in the Label component and recompile the application.

Using regular expressions, you would simply need to change the locale data. Depending on your setup, you might not even need to reload your application!

Regular Expressions + Locale Data = Happy Applications :)

Data binding in Flex is a great tool for automatically linking the data in your model to your view.

However when you want to define your own bindable data sources through the use of getters and setters, the bindings don’t seem to work.

So what’s the solution?

The trick is to first define a bindable event for your getter:

[Bindable(event="propertyChange")]

You then need to dispatch this event whenever the property changes within your setter:

dispatchEvent (new Event ("propertyChange"));

That’s all there is to it!

Whenever your property changes (via the setter method), an event is dispatched that notifies any components linking to the property (via the getter method) that the property has been updated.

Here’s some example code you can enjoy with a glass of awesome:
http://userflex.wordpress.privatepaste.com/5eyyVQcWwq

Update: Code snippets I’ve posted using Private Paste are randomly disappearing, so if the above link no longer exists, here’s a backup.

The Adobe® Flex® 3 Language Reference provides some great examples when it comes to accessing XML elements and attributes using e4x.

However what it doesn’t show you is how to access those same elements and attributes when the XML object contains one or more namespace declarations.

Consider the following XML sample:

var response : XML =
<response xmlns:sample=”http://userflex.wordpress.com/”>
<statusCode>200</statusCode>
</response>;

Because of the namespace declaration, you can’t simply access the statusCode element with response.statusCode, despite the fact that the statusCode element resides in the default namespace.

What you need to do is iterate over the set of XML namespaces until you locate the default namespace. Then you can access any of the XML elements or attributes in the default namespace in nearly the same manner as before.

without namespaces:
response.statusCode

with namespaces:
response..xmlns::statusCode

In the above example, xmlns would be a Namespace object that references the default XML namespace.

Check out the tasty sample code here:
http://userflex.wordpress.privatepaste.com/cduVt2tL2i

Update: Code snippets I’ve posted using Private Paste are randomly disappearing, so if the above link no longer exists, here’s a backup.

I’ve noticed that when I create multiple Window top-level containers in an AIR application, the memory they consume never appears to be garbage-collected, even after the windows are closed and their references destroyed.

This may be an unusual problem, since most AIR applications simply make use of the WindowedApplication container for their initial (and only) window.

For now, the only workaround available is to simply reuse AIR windows instead of closing them - which means the memory leak is only as bad as the maximum number of windows I need to have visible at once.

Where’s free() when you really need it? :-)

The Text control in Flex allows you to display non-editable, multi-line text with basic HTML markup.

But there’s a problem when it comes to anchor tags.

If you set the selectable property in the Text control to false, as I often do, the links in your HTML text will no longer work.

Believe it or not, this is by design!

From the Adobe® Flex® 3 Language Reference (emphasis added):

selectable property
selectable:Boolean [read-write]

Specifies whether the text can be selected. Making the text selectable lets you copy text from the control.

When a link event is specified in the Label control, the selectable property must be set to true to execute the link event.

The default value is false;.

So it seems that if you want the links in your Text control to remain clickable, the HTML text must be selectable.

(Not the biggest deal of course, but it would have been nice to know before I spent an hour pouring over my code at 1am trying to figure out why my links weren’t working) :-)

Flex 3 makes it easy as pie to transform a series of images into a custom Button control.

First, create a CSS style declaration for your button, and define a different skin for each image you want to use. Even if you only have a single image, you’ll still want to implement the basic upSkin, downSkin, overSkin and disabledSkin style properties.

To embed an image asset in CSS, use the following syntax:

up-skin: Embed("pathTo/myImages/Up.png");

Once you’ve created your CSS style declaration, you’ll need to reference it in the styleName property of your Button control.

Finally, since we’ve replaced the default chrome with a custom set of images, the mouse cursors won’t behave like they would for a normal button. To fix this, we need to enable the buttonMode property and disable the mouseChildren property in the button.

That’s all there is to it!

Sample code for the CSS:
http://userflex.wordpress.privatepaste.com/d1JLaHSoi8

Sample code for the MXML:
http://userflex.wordpress.privatepaste.com/aaZFSzU9E0

The StyleManager class in Flex allows you to easily read and write individual style properties from the comfort of your AS3 code.

But it’s not as easy as it could be.

You still have to retrieve each style declaration, make sure they exist, and then either return or set the desired style property. It’s not a lot of work, but it’s repetitive, and we can do better.

Enter the StyleUtil class.

StyleUtil is an all-static class I created with methods to access and modify individual style properties.

There are two basic methods, setCSSStyle() and getCSSStyle(), as well as hex() and hexToString() methods for converting hexadecimal values.

Now, changing the background color of a Canvas container is as simple as calling:

StyleUtil.setCSSStyle ("Canvas", "backgroundColor", StyleUtil.hex (value));

Not too shabby, eh?

Full source code is available here:
http://userflex.wordpress.privatepaste.com/241rTkjoRl

As well as a few sample getters and setters:
http://userflex.wordpress.privatepaste.com/ceKcBegdpA

Update: Code snippets I’ve posted using Private Paste are randomly disappearing, so if the above link no longer exists, here’s a backup.

When you create a custom item renderer for a List control you need to be very careful how many layout constraints you introduce in each component. What might seem harmless in a single item can quickly become a performance bottleneck when that item is recreated several hundred times in a list.

A few general rules of thumb:

Use exact measurements
This one is obvious. By specifying an exact location (x, y) and size (width, height) you reduce the number of constraints your application has to keep track of. While the effect may be minimal, it can really make a difference when manipulating large data sets.

Don’t abuse the maxWidth property
I learned this the hard way. Setting the maxWidth property on as few as two components in an item renderer can ground your application to a halt, even with as few as a dozen items in your List control.

Don’t resize components using percentage widths
This applies to complex item renderers that have one or more components that set the maxWidth property, but in general its a good idea to resize your components absolutely. Even if you can only shave a few milliseconds off the rendering time it can make your application feel that much more responsive.

Avoid nesting containers
In general you should use as few containers as possible in your application, and item renderers are no exception. Nested containers create layer upon layer of constraints and can unnecessarily slow down your application. If you can, use a single layout container, and if at all possible, use a Canvas container with absolute positioning. Even HBox and VBox containers are heavier than Canvas.

Use Resize and Move effects instead of changing (x, y, w, h) directly
Although it may seem counter-intuitive, using effects can actually improve the performance of your application. Processing large amounts of information when you move or resize components can result in your application being unresponsive. But if you use effects, you can take advantage of the suspendBackgroundProcessing property to block all background processing while your components are being moved or resized. Even if you set the effect duration to 0ms you will still see an improvement in performance!

To summarize, when creating custom item renderers and List controls, be aware of the effect your design decisions will have, especially on larger data sets. What may seem to be insignificant data-bindings can quickly add up to huge performance problems!

I often need to store a fixed amount of frequently-changing information, like when I want to keep track of the last ten messages posted in a chat room or the five most recently viewed items in an online store.

In these situations I use a MaxSizeArrayCollection object I developed that works like a regular collection but with an enforced maximum size.

The beauty of this object is that it removes any need to manage the size or contents of the collection. No trimming, no sorting - no worries.

So how did I do it?

First off, I created a custom AS3 class that extends ArrayCollection and specifies a maximum size in the constructor. Second, I overrode the addItem() and addItemAt() methods to check the size of the collection before adding a new item.

When your collection is at its maximum size, you can take several actions depending on how to you want the collection to be maintained.

The method I used is to simply remove the first item in the collection before adding a new one (FIFO for those familiar with stacks and queues). This guarantees that my collection always contains the latest set of information.

Pretty nice huh?

Check out the sample code:
http://userflex.wordpress.privatepaste.com/191QoRUHyR

TabNavigator containers come with a handful of styles that allow you to customize the appearance of the tabs:

tabStyleName
Name of CSS style declaration that specifies styles for the tabs. The default value is undefined.

firstTabStyleName
Name of CSS style declaration that specifies styles for the first tab. If this is unspecified, the default value of the tabStyleName style property is used.

lastTabStyleName
Name of CSS style declaration that specifies styles for the last tab. If this is unspecified, the default value of the tabStyleName style property is used.

selectedTabTextStyleName
Name of CSS style declaration that specifies styles for the text of the selected tab.

But sadly, you cannot easily specify a CSS style declaration for the selected tab. You can only specify a style for the text of the selected tab.

This sucks.

Luckily, there is a better way to customize the appearance of the tabs, without being constrained or limited by the styles mentioned above. You can skin them!

In the CSS for your application, create a new style declaration for your tabs. Then define values for any or all of the skin properties: skin, disabledSkin, downSkin, overSkin, upSkin, selectedDisabledSkin, selectedDownSkin, selectedOverSkin, selectedUpSkin.

Now this is where it gets beautiful. The values you specify for the skin properties can point to custom components OR embeddable assets!

You can use ClassReference() to specify custom components and Embed() to specify custom assets like images or SWFs.

What’s great about this solution is that you can also use the standard TabNavigator styles in tandem with the custom skins.

This means you can skin the tab backgrounds with a GradientCanvas container, for example, and use the tabStyleName and selectedTabTextStyleName styles to customize the tab fonts!

Update: I’ve posted sample code below that uses a Canvas container and some basic black-and-white styles to demonstrate how this works!


Sample code for the custom styles:


.tab
{
     up-skin: ClassReference(”TabSkin”);
     down-skin: ClassReference(”TabSkin”);
     over-skin: ClassReference(”TabSkin”);

     selected-up-skin: ClassReference(”SelectedTabSkin”);
     selected-down-skin: ClassReference(”SelectedTabSkin”);
     selected-over-skin: ClassReference(”SelectedTabSkin”);

     background-color: #FFFFFF;

     font-weight: normal;
     color: #000000;
     text-roll-over-color: #000000;

     corner-radius: 0;

     border-style: solid;
     border-thickness: 1;
     border-color: #000000;
}

.selectedTab
{
     background-color: #000000;

     font-weight: bold;
     color: #FFFFFF;
     text-roll-over-color: #FFFFFF;

     corner-radius: 0;

     border-style: solid;
     border-thickness: 1;
     border-color: #000000;
}



Sample code for the tab skins:


package
{
     import mx.containers.Canvas;

     public class TabSkin extends Canvas
     {
         override protected function updateDisplayList
             (w : Number, h : Number) : void
         {
             this.styleName = “tab”;

             super.updateDisplayList (w, h);
         }

     }
}

package
{
     import mx.containers.Canvas;

     public class SelectedTabSkin extends Canvas
     {
         override protected function updateDisplayList
             (w : Number, h : Number) : void
         {
             this.styleName = “selectedTab”;

             super.updateDisplayList (w, h);
         }

     }
}



Sample code for the TabNavigator container:


<mx:TabNavigator id=”tabs”
    tabStyleName=”tab” selectedTabTextStyleName=”selectedTab” />

Runtime styles are great. They allow you to dynamically change the look-and-feel of your application, and they reduce the size of your deployed SWF.

But when you load your style SWF at startup, there is a potential delay between when your application is displayed and your runtime styles are applied.

Why does this matter? Because in that minute fraction of time your application is visible before your runtime styles are applied, the default Flex styles are visible. The result is a not-so-subtle flicker as your styles change.

Fortunately, there is an easy solution.

It turns out you can prevent the Flex preloader from disappearing until your runtime styles have been loaded. If you override the initialized setter in your main MXML file, the preloader will not disappear until you call super.initialized = true.

Sample code for loading runtime styles:
http://userflex.wordpress.privatepaste.com/140mdMhCvg

The Canvas layout container. We all know it, we all love it. Lets us place our components wherever we like. Such a good sport.

But the one aspect I dislike about the Canvas container is the lack of a background gradient. Why should buttons have all the fun?

After reading through the source code for the Canvas container and Button control, I realized creating a Canvas with a background gradient would be pretty easy, so long as I was willing to tinker around with the drawing API.

Which I was.

So how did I do it? I extended the Canvas container in a new AS3 class, and overrode the updateDisplayList() method. That’s it.

The beauty of this is that it doesn’t mess with the layout of the child components in the container. It just makes the background a whole lot prettier.

Sample code for the GradientCanvas:

package
{
    import mx.containers.Canvas;
    import mx.styles.StyleManager;
    import mx.utils.ColorUtil;

    public class GradientCanvas extends Canvas
    {
        override protected function updateDisplayList
            (w : Number, h : Number) : void
        {
            super.updateDisplayList (w, h);

            // retrieves the user-defined styles
            var fillColors : Array = getStyle (”fillColors”);
            var fillAlphas : Array = getStyle (”fillAlphas”);
            var cornerRadius : Number = getStyle (”cornerRadius”);

            // converts the fill colors to RGB color values
            StyleManager.getColorNames (fillColors);

            // ready to draw!
             graphics.clear ();

            // draws the gradient
            drawRoundRect (0, 0, w, h, cornerRadius, fillColors,
                fillAlphas, verticalGradientMatrix (0, 0, w, h));
        }
    }
}


You’ll notice in the code that I only check for the fillColors, fillAlphas and cornerRadius styles in my component. That’s all I really needed for my GradientCanvas container, but if you wanted to add support for borders and shadows you would simply add the styles and draw them as well.

Piece of pie.

I love Flex, but the default scrollbars are hideous. Sure, you can customize a couple of values in the CSS, the track and fill colors, etc. But those stupid arrow buttons are still there, sucking up the good vibes from the rest of your application.

So how do we get rid of them?

First, create a custom class that extends ProgrammaticSkin. Override the updateDisplayList() method in this class and leave it blank. Don’t even invoke the super.updateDisplayList() method!

Second, add a class reference to your CSS file for each of the up and down arrow skin properties.

Voilà! The arrow buttons are gone! :-)

Update: I’ve posted sample code below to replace the dead Private Paste URLs.


Sample code for the custom skin:

package
{
     import mx.skins.ProgrammaticSkin;

     public class NoArrowSkin extends ProgrammaticSkin
     {
         override protected function updateDisplayList
             (w : Number, h : Number) : void
         {
         }
     }
}



Sample code for the custom styles:

ScrollBar
{
     upArrowDisabledSkin: ClassReference(”NoArrowSkin”);
     upArrowDownSkin: ClassReference(”NoArrowSkin”);
     upArrowOverSkin: ClassReference(”NoArrowSkin”);
     upArrowUpSkin: ClassReference(”NoArrowSkin”);

     downArrowDisabledSkin: ClassReference(”NoArrowSkin”);
     downArrowDownSkin: ClassReference(”NoArrowSkin”);
     downArrowOverSkin: ClassReference(”NoArrowSkin”);
     downArrowUpSkin: ClassReference(”NoArrowSkin”);
}