You are currently browsing the monthly archive for February, 2008.

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