Restoring default Flex tree icons

I came across this gotcha recently when working on a Flex Tree component where I wanted to use custom icons. The Flex component has a attribute “iconFunction” that can be used to return a custom icon based on whatever logic you want. In my case, I was satisfied with the default closed and open folder icons that the component uses, but wanted to override the leaf node icons. I started with a Tree tag, such as:

<mx:Tree id="tr1" dataProvider="{model.xmlTreeData}" labelField="@label"
     iconFunction="getTreeIcon"
     click="handleTreeClick(event)" />

which uses a simple XML document to construct the tree. The XML tags that make up the leaf nodes of the tree all have a “department” attribute. I have an icon for most departments as well as a default. If you use “iconFunction” the Tree will expect the custom function to return something for both folders and leaves. The trick here was to reference the folderOpenIcon and folderClosedIcon that are styles on the Tree itself. Here’s my custom icon function:

private function getTreeIcon( item:Object ):Class
{
   if ( tr1.dataDescriptor.hasChildren(item) ) {
      if ( tr1.isItemOpen(item) ) {
         return tr1.getStyle("folderOpenIcon");
      }
      else {
         return tr1.getStyle("folderClosedIcon");
      }
   }
   else {
      var treeNode:XML = item as XML;
      var department:String = String(treeNode.attribute("department"));
      switch ( department ) {
         case "hr" :
            return icoHR16;

         case "shipping" :
            return icoShipping16;

         case "retail" :
            return icoShoppingCart16;

         case "accounting" :
            return icoCalc16;

         default :
            return icoDoc16;
      }
   }

   return icoDoc16; // should never be reached
}

This function first checks to see if the passed item has any children (that is, to see if it’s a folder) – if so, it returns the appropriate style either open or closed. Otherwise it assumes it is a leaf node and looks for a defined “department” icon.

I’m not sure if this is the best way to do this (mainly due to the heavy coupling between the icon function and the specific Tree instance), but it worked for me and thought it might be a common enough scenario that others might benefit from this example. If there’s a “right” way to do this, please let me know!

Advertisements
This entry was posted in development and tagged , . Bookmark the permalink.

2 Responses to Restoring default Flex tree icons

  1. Nussy says:

    Thank you!

  2. kanenas says:

    The default icons are in Assets.swf, which is somewhere on the classpath (this info came from Adobe’s Tree style summary). You can embed these resources into your custom control when it’s compiled.

    [Embed(source="Assets.swf",symbol="TreeFolderClosed")]
    private var treeFolderClosedIcon:Class;

    [Embed(source="Assets.swf",symbol="TreeFolderOpen")]
    private var treeFolderOpenIcon:Class;

    ...
    private function getTreeIcon( item:Object ):Class
    {
    if ( tr1.dataDescriptor.hasChildren(item) ) {
    if ( tr1.isItemOpen(item) ) {
    return treeFolderOpenIcon;
    } else {
    return treeFolderClosedIcon;
    }
    }
    ...

    I prefer the way you posted of getting the folder icons from the tree’s style info (especially when creating reusable components), as using style rather than static icons is more flexible. The coupling between the icon function and a Tree instance is entirely appropriate.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s