Director of Consulting Services for Universal Mind

I have been consulting with a stellar group of IT professionals at Universal Mind now since April 2007.

My history (9 yrs) with the founders of Universal Mind goes back to Allaire and Macromedia consulting. Our network was formed through this highly cohesive team of consultants that was built to support what I feel is still the best RAD server side technology on the market; ColdFusion.

With our current company focus on RIA, Flex, AIR, Java, ColdFusion and the various infrastructure technologies they integrate with in the modern enterprise I have been able to contribute and witness how companies benefit instantaneously from the services we provide.

It was an honor to be offered the full time directorial position with Universal Mind recently and I am very much looking forward to future challenges and continued successes in this role with UM.

On a final note UM is always looking for great developers, system architects, and designers. Don't hesitate to respond to this blog with any interest. And if you find yourself reading this blog looking for talent due to a demanding project, please reach out to me; UM can "parachute" an expert or team of experts into your office quickly to help assist you with the challenges you may be experiencing no matter what SDLC phase you are in.

Quick Blog (Use mx:Form)

I have been too busy to blog over the past couple months and this is more of a note than a blog entry. I have come across a few applications in the past 6 months that had your standard CRUD forms.

The problem is that most of them used HBOX and VBOX in attempt to align Labels and TextInput items. ACKKK! These can significantly increase the size of your swf after compile in Flex Builder. For form layout you can almost always use mx:Form. The feature set behind this tag is very intuitive as well.

I've seen developers write code to handle key press of the enter key in an effort to trigger the firing of a default button on the form. This is incorporated in the mx:Form tag also; you just point to the button via the defaultButton property. The default button will fire when you click enter key on text input items.

I have attached a simple example of mx:Form with a default button displaying an alert. Hope this helps and check out the language reference for more info as I didn't touch on all features: mx:Form

Sample App:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" viewSourceURL="srcview/index.html">
   
   <mx:Script>
      <![CDATA[
         import mx.controls.Alert;
         
         private function showAlert(event:MouseEvent):void
         {
            Alert.show('You submitted the form dude. ' + 'Form Data: ' + formField.text );
         }
         
      ]]>
   </mx:Script>
   
   <mx:Form x="0" y="0" width="447" height="488" defaultButton="{submitButton}">            

         <mx:Label id="exampleForm" text="Example Form" />
         <mx:FormItem id="lblFormField" label="Form Field:">
            <mx:TextInput id="formField" enabled="true" cornerRadius="4" text="Default text." toolTip="Enter some text."/>
         </mx:FormItem>
         <mx:FormItem width="409" height="25">
            <mx:Button id="submitButton" label="Submit" click="showAlert(event)"/>   
         </mx:FormItem>      
      </mx:Form>

   
</mx:Application>

A Mashup That Makes Sense

Recently Andy Powell won a WII for his submission into the 360 Flex | API Contest.

His winning application is a great example of leveraging multiple APIs that at first glance, one may be challenged in connecting the dots with regard to how they could be integrated into a single intuitive application. When I first looked at Andy's initial layout and functionality as intuitive as it was, I got stoked because I could see that this application could be enhanced visually and functionally; so I am blogging about the enhancements I made to that effect.

First, I had some .css in mind to give it that Ribbit Green theme. I adjusted the layout of the various nested canvases and converted them to use a form which allows for formitem conciseness with regard to alignment etc and allots for a default button (integrated form 'enter key' functionality).

I sized down the respective API images into the main panels control bar (will be applying links shortly) and enhanced the map functionality which allows for a unique icon (hotel) to identify the selected hotel from other hotel POIs on the map. Each time a search is performed the past icon is returned to its initial state and the newly selected hotel gets the new icon (member variables used to allow for this). I will be styling the MapQuest info windows that pop up with selection of a POI shortly as the very customizable MapQuest API is 100% extensible.

I then relocated the RIBBIT dial up interface and adjusted dialing status to persist in the connection labeling area rather than separately at the bottom of the form to save real estate. Lastly, I wrapped it in a panel with the hotel details form and nested it within a panel along with the MapQuest tilemap component. This panel will soon be a slide in that will open/close via grid selection and panel close feature. Please check out the new app on Andy's site here; Ribbit, Kayak, MapQuest Mashup and book your hotel today 8-).

FYI, souce code is located at Andy's Google code site here: AP's GCode site

Flex Smart Combo (aka look ahead combo)

A few weeks back a fellow UM-er asked if there had been a look ahead combo created at some point and possibly checked into our library.

To my knowledge such a component didn't exist except for a few components running around that didn't exactly do what he was looking for. So I spent some time extending combo box to create the functionality he was looking for.

This component allows a user to hot key filter the combos list/data provider which means, when the combo box gains focus it becomes editable allowing key entry to filter the list items based on the keys pressed.

It is quite slick and is written entirely as a single class extending ComboBox. Feel free to enhance, chop, criticize... It's yours to use how you wish and I hope it assists you in your efforts. Enjoy!

I would like to thank Adam Flater for adding case sensitivity option and label filtering. Check out his blog: Here

********* UPDATE: 6/26/2008 ************

Resolved focus issues. Enabled view source (right click on the swf).

package com.universalmind.controls
{
import flash.events.Event;
import flash.events.FocusEvent;
import flash.events.MouseEvent;

import mx.controls.ComboBox;

public class SmartCombo extends ComboBox
{
private var _trackText:String = "";
private var _caseSensitiveSearching : Boolean = true;

public function SmartCombo()
{
//TODO: implement function super();
}

public function set caseSensitiveSearching (bool : Boolean) : void {
_caseSensitiveSearching = bool;
}

public function get caseSensitiveSearching () : Boolean {
return _caseSensitiveSearching;
}

override protected function textInput_changeHandler(event:Event):void {
_trackText = this.textInput.text;

// variables used in the loop var label : String = null;
var matchingIdx : int = 0;
var foundMatch : Boolean = false;
var searchString : String = this.textInput.text;

if ( caseSensitiveSearching == false ) searchString = searchString.toLowerCase();


// using a for each loop on dataProvider does not strongly // couple to it only being an ArrayCollection... simlar // with weak typing on the items in the set for each ( var item : Object in this.dataProvider )
{
// using itemToLabel() checks a few things like // if the item is a String, or it there's a // labelFunction being used label = this.itemToLabel( item );


// if searching should not be case sensitive // do a toLowerCase() on label if ( this.caseSensitiveSearching == false )
{
label = label.toLowerCase();
}


// find the first item that starts with searchString // if there's a match, break out of the loop if ( label.substr( 0, searchString.length ) == searchString )
{
this.dropdown.selectedIndex = matchingIdx;
this.dropdown.scrollToIndex( matchingIdx );
foundMatch = true
break;
}
matchingIdx++;
}


// if there was no match found set selectedIndex to -1 // (unselect the list) if ( foundMatch == false )
{
this.dropdown.selectedIndex = -1;
}
}

override public function close(trigger:Event=null):void{
super.close(trigger);
if (this.text == "")
{
this.selectedIndex = 0;
}
this.editable = false;
}

override protected function focusOutHandler(event:FocusEvent):void
{
super.focusOutHandler(event);
if (this.text == "")
{
this.selectedIndex = 0;
}
this.textInput.selectionEndIndex = this.textInput.width;
this.editable = false;
}

override protected function focusInHandler(event:FocusEvent):void
{
super.focusInHandler(event);
this.editable = true;
this.textInput.setFocus();
this.open();
}


}
}

Example:

Download Source Project: Here

Render Me This

I was recently working with item renderers on a project and wanted to post an example of using an ActionScript (class) based item renderer and compare it with an MXML version.

It is nice to have the option to choose either, but I like the control an ActionScript class gives the coder and it tends to yield a more lightweight approach than MXML.

My first code block below is the AS class approach. The renderer simply applies a currency format to a field of numbers in a data grid. The second is utilizing the MXML approach. As you can see they yield the same results.

Notice how both approaches override the data setter for the label class they extend. Also see how how listData is utilized to associate the drop-in item renderer with the data from the list control.

With this rather basic example you can see how any control can be displayed via MXML or ActionScript and drawn out i.e. rendered in a list based class.

I have attached a zipped project that displays 2 grids using both renderers. I hope this helps you better understand the power of item renders and what you can do with them.

********* UPDATE: ************

I forgot to mention in this blog that a custom label could be applied via the DataGridColumn labelFunction to get the same effect in assigning a currency symbol.

Please see an example of the code below.

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
<![CDATA[
import mx.controls.dataGridClasses.DataGridColumn;
import mx.collections.ArrayCollection;

[Bindable]
private var cars:ArrayCollection = new ArrayCollection( [
{ Make: "Infiniti", Model: "G37", Year:2008, Cost: 44081 },
{ Make: "Lexus", Model: "IS 350", Year:2008, Cost: 45205 },
{ Make: "BMW", Model: "3 Series", Year:2008, Cost: 49100 } ]);

// this function is call via the DataGridColumn labelFunction // and it utilizes the CurrencyFormatter below private function currencyLabelFunction(item:Object, column:DataGridColumn):String {
return cf.format(item["Cost"]);
}      

]]>
</mx:Script>

<mx:CurrencyFormatter id="cf" precision="2"/>

<mx:Panel title="Label Function Example" layout="horizontal">

<mx:DataGrid dataProvider="{cars}" id="labelFuncCars">
      <mx:columns>
            <mx:DataGridColumn headerText="Make" dataField="Make" width="60" />
            <mx:DataGridColumn headerText="Model" dataField="Model" width="60" />
            <mx:DataGridColumn headerText="Year" dataField="Year" width="60" />
            <mx:DataGridColumn headerText="Cost" dataField="Cost" width="100" textAlign="right" labelFunction="currencyLabelFunction" />
      </mx:columns>
   </mx:DataGrid>

</mx:Panel>
</mx:Application>

CurrencyRendererAS Class

package renderers
{
import mx.controls.Label;
import mx.controls.dataGridClasses.DataGridListData;
import mx.formatters.CurrencyFormatter;

public class CurrencyRendererAS extends Label
{
private var cf : CurrencyFormatter = new CurrencyFormatter();

public function CurrencyRendererAS()
{
super();

// set precision for formatter cf.precision = 2;
}

// Override the set method for the data property. override public function set data(value:Object):void {
super.data = value;

if (value != null)
{
this.text = cf.format(value[DataGridListData(this.listData).dataField]);
this.setStyle("textAlign","right");
}

super.invalidateDisplayList();
}
}
}

CurrencyRendererMXML MXML

<?xml version="1.0" encoding="utf-8"?>

<mx:Label xmlns:mx="http://www.adobe.com/2006/mxml"
width="100%">

   <mx:CurrencyFormatter id="cf" precision="2"/>
   
<mx:Script>
<![CDATA[
import mx.controls.Label;
import mx.controls.dataGridClasses.DataGridListData;
import mx.formatters.CurrencyFormatter;

      override public function set data(value:Object):void {
super.data = value;

if (value != null)
{
this.text = cf.format(value[DataGridListData(this.listData).dataField]);
this.setStyle("textAlign","right");
}

super.invalidateDisplayList();
}
]]>
</mx:Script>
</mx:Label>

AS Approach Output

MXML Approach Output

Label Function Output

Subclipse Bug on Flex Bldr Beta 3 Standalone on XP/Vista

I found myself grasping at straws on this one. Thank the folks on the beta debug team and their public bug tracking system.

The answer (walkthrough) is below, check the link for the details if you are interested.

Work around is:

- Help > Software updates > Find and install. Select search for new features to install.

- Check the Europa discovery site and the SubEclipse update site. (add the SubEclipse site via 'New Remote Site' if it isn't present http://subclipse.tigris.org/update_1.2.x/ )

- Click finish.

- Check SubEclipse and in the Europa discovery site check "Eclipse Java Development Tools" under "Java Development".

- Click next and complete the wizard.

Note, make sure you only select the Subclipse sub-category or it will still bomb.

The bug at Adobe.com: Subclipse SVN plugin requires the feature org.eclipse.jdt

Flex Job Growth (Indeed.com showing 1500%)

So you are wondering if Flex is a viable career choice..? I have been out to this site before, but have been wanting to blog about it for some time.

At the time of this blog Flex demand in the job market is up 1500%. This is pretty much unmatched to any other IT job search on Indeed.com from what I could find.

Why VOs (transfer objects) are good...but they can be abused like...

any other design pattern....

Sorry for the confusing title, but long titles are rather lame. So you're a flex cf, java, or php developer and you are leveraging all the beautiful one to one mapping associated with server and client object creation.

"YES!", you said. No more guess work; my server vals returned can be readily passed around within my AS code with the ease of code insight! Ctrl-space... wow theres my property! Ok, getting tacky I know.

So we embark on our design of a sytem always using VOs no matter the cost. Eee gaadd stop now. VOs, pending on design approaches may possibly have multiple layers of nested VOs YIKES!

Everyone knows that Rambo's weapons of choice were the bone cutting hunting knife and explosive bow and arrows. But there were times when he had to pull in the heavy artillery or perform a sneak attack with a much more lightweight approach like a choke hold (ahh, the violence of my youth...).

This is why VOs can be a problem if implemented without understanding the performance ramifications that can be incurred if they are always used.

Here's a real world scenario. Requesting an array of 100+ VOs from your middle tier that each have nested arrays of child VOs. Imagine just having two child VOs and the impact that could have on performance with this approach.

You call in to pull back the parent VOs that contain an array of child VOs (say 5) that all need to get created for each item in the array. So in this process we are creating 100 parent objects and internal to each we are creating 10 child VOs. This yields 1000 objects which each need to get created and the memory and process grow each time you do so on your middle tier (now add just a few users doing this incrementally over the first couple of hours).

I'm being facetious here of course as this isn't a very high number. But why return such a dense object to the client unless you were going to use it. There is a lot of wasted horsepower with this approach. Think of the scene with Rambo emptying that M60 E4 machine gun and never hitting his target... Rambo

A better approach is to pass back a snapshot of the data directly from your middle tier and pull back its VO representation when an edit needs to be performed or the VO truly is required to facilitate a process in the application.

So if you are going to populate a grid, I don't recommend doing it with VOs and if you absolutely have to create an array of VOs understand the possible performance impact (and data stagnation) that can ensue if the VO is of a complex nature and how it can impact the health of your server and ultimately the user experience.

The J2EE Core Pattern docs on Transfer Object speak to this. Check out the "Consequences" section of caching large sets of VOs. Line from the article: There is a trade-off associated with this strategy. Its power and flexibility must be weighed against the performance overhead... THE LINK

Flex ColdFusion Extension Wizard Gotcha

This entry will hopefully be brief and to the point in regard to the title. I want to start off by stating how much I like the ColdFusion extension support in Flex 2 and hope to see Adobe add extenstions that support other languages/middle tier solutions as well hint: (java, php, c#).

There is nothing like beginning your application architecture and development with an out of the box mvc approach utilizing well known approaches to server side development utilizing delegates, services, daos, gateways, and value objects.

Where I see a major problem with the extension is how it is implemented. I have been involved with several projects that have utilized Flex and ColdFusion and upon initially beginning my trek into Flex 2 I saw this issue right away only because I have been working with ColdFusion for 10 years, have consulted on its benefits, scaled servers, architected highly successful and efficient enterprise solutions with it, and know the do's and don'ts...

The problem I am speaking of with the CF extension implementation is the iterating over read functions in the data access object cfcs.

To be more clear, in the templated or skeleton dao cfcs there are db calls made, mostly crud calls. The read function I am discussing here is "r" in crud. The problem is that in many cases I've seen engineers design a composite or aggregate VO. This is a VO cfc that contains other VO cfcs.

This is a perfectly efficient and best practice OOP approach that ColdFusion handles very well. The problem arises when a child resultset of ids (usually a query or array) is used to iterate over and call the read function in the dao to get the vo properties from the db to return via remoting to the Flex application.

The main issue here is performance, specifically with the possible 100s of calls that can be made to the database in one ColdFusion request from the application. Imagine a dump truck going 200 times to the gravel pit taking one pebble, with today's gas prices I don't think you'd last long on the job if you took that approach 8-)... This is what you are doing when you loop over queries. Not only could these calls prove to be slow and taxing on the database but it can also lock up threads in ColdFusion and create cpu and memory spiking out of the shoot. You also have to deal with any kind of network latency that may exist between your CF server and the database as well. AAAACKKKKK!

But there is a solution: First a band-aid needs to be applied. For these complex objects an investigation must be made to locate where these iterating processes could be going on. Second, there is a function in ColdFusion that automagically converts a query field to a comma-delimited value list(or delimiter of your choosing). The function is called "valueList(query.column, ',')" there is also a quotedValueList for strings. With this list you could then use the SQL IN clause on the hopefully indexed id field used to pull back the child VO data. Add another function in the dao or better yet the data gateway that specifies readMultiple or getMulipleObjectName...

Once this is done the code should truly be refactored to call the database only once for all its data (think one cf call/one db call). If you did not know ColdFusion is one of the most robust languages when integrating with the more popular dbms on the market (Oracle, SQL Server, MySQL, DB2, Informix). The cfstoredproc tag allows you to call into a stored procedure to get procedure resultsets.

cfstoredproc also allows a developer to return multiple resultsets from a stored procedure to ColdFusion. So, one call to a stored procedure in Oracle that returns 2,3,4,or more ref cursors to ColdFusion. These could be all your objects' data which only requires you to loop once over all of them (maybe some nesting and brief logic to create them, but still 1000s of times faster than separate db calls for each loop).

This may be one of the drier entries I've had (no code, pictures, jokes). But I hope it helps you when using and not abusing the ColdFusion extension wizards in Flex 8-).

Universal Mind is Blogging

Check it out here: UM Blog.

UM is made up of a bunch of stellar Adobe and related software IT professionals. They have some incredible information to share with regard to Flex, Flash, AIR, CF, Java, etc. and we can all learn from them. Enjoy!

More Entries


Copyright Strikefish, Inc., 2005. All rights reserved.