| By Victor Rasputnis, Yakov Fain, Anatole Tartakovsky | Article Rating: |
|
| November 20, 2006 08:45 PM EST | Reads: |
58,539 |
Runtime Column Styles Unleashed
Here is the plan:
we will upgrade the default itemRenderer of the fx:DataGrid from
UITextField to our custom fx:Label by extending fx:DataGridColumn with
an extra property - runtimeStyles. Finally, we will intercept data
changes to an item renderer, whether default or not, to re-assign all
runtimeStyles on each.
Here is how the constructor of the standard DataGrid assigns itemRenderer:
package mx.controls {
public class DataGrid extends DataGridBase implements IIMESupport
{
public function DataGrid()
{
super();
itemRenderer = new ClassFactory(DataGridItemRenderer);
. . . . . .
}
}
}
We would have to fight the instant temptation to replace the assignment of the itemRenderer with:
itemRenderer = new ClassFactory(com.theriabook.controls.Label);
Here is why: a ClassFactory instance is a "factory object," which is used to generate instances of another class (aka generator class) with the newInstance() method. According to our plan, we need to intercept data changes to any instance of the generator class item renderer. In other words, we'll need to listen to the event FlexEvent.DATA_CHANGE on every instance of the com.theriabook.controls.Label created by "the factory." Hmm, what could be simpler than adding the needed event listener to the controls? Although we are content with the fx:Label as a default renderer, by no means do we propose to take the power of the custom item renderers away. To make the mechanism of the runtimeStyles control agnostic, we would like to listen to FlexEvent.DATA_CHANGE on the instances of any generator class.
It only sounds difficult. After all, a ClassFactory is nothing but an implementation of the IFactory interface with a single property - properties and single method - newInstance(). So we can easily wrap a standard ClassFactory inside our custom one for the purpose of intercepting the newInstance() call. We will call our wrapping class factory the UIClassFactory:
function DataGrid() {
super();
itemRenderer = new UIClassFactory(ClassFactory(com.theriabook.controls.Label));
}
The constructor of the UIClassFactory would simply store the reference to the instance of the real class factory - cf. The newInstance() would delegate the call to the cf.newInstance(). In addition, it would also register the listener to FlexEvent.DATA_CHANGE event, as shown below:
public class UIFactory implements IFactory
{
. . . . .
public function UIClassFactory( cf:ClassFactory ) {
wrappedClassFactory = cf;
}
public function newInstance():* {
var obj:* = wrappedClassFactory.newInstance();
obj.addEventListener(FlexEvent.DATA_CHANGE, onDataChange);
return obj;
}
private function onDataChange(event:FlexEvent):void{
. . . . .
}
}
As a reminder, the properties of the factory-manufactured objects get assigned by iterating over properties of the specific property of the factory object. The name of this aggregating property is properties. That way all instances are initialized with the same values. Wrapping up the property properties is quite simple:
public function set properties(v:Object):void {
wrappedClassFactory.properties = v;
}
public function get properties():* {
return wrappedClassFactory.properties ;
}
The complete code for UIClassFactory is available in Listing 7.
Let's talk about the onDataChange() handler. The implementations of both IDropInListItemRenderer and IDataRenderer events are sending us DATA_CHANGE events. We start by filtering out the events coming from the IDropInListItemRenderer part and leave only the ones coming from IDataRenderer. Then we single out the runtimeStyles property and treat it as a dynamic object carrying the property names that correspond to the style names. The values of these properties may be literal or, alternatively, the function references. In the latter case, we apply the call operator () prior to setting the style value with the setStyle().
One chore remains. As long as we want to communicate the runtimeStyles to any item renderer, including the ones that are individually set on a per column basis, we need to modify our DataGridColumn, overriding the implementation of the DataGridColumn's itemRenderer setter:
override public function set itemRenderer( val : IFactory ) : void {
super.itemRenderer = new UIClassFactory(val as ClassFactory);
}
The code for our DataGridColumn is shown in Listing 8, and Listing 9 has our test application RuntimeStyleDemo. Figure 5 depicts the RuntimeStylesDemo running.
What's the cost of our automation? We have replaced the ultralight UITextField with the heavier UIComponent - Label so there must be a potential for performance degradation. On the other end, the DataGrid recycles item renderers by maintaining a pool of them just enough to cover the visible portion of the column, which outright limits possible damage.
o far we have shown that it is possible to control runtime styles via anonymous or explicit functions (backgroundColor versus computedFontWeight in the above demo application). You can take our approach further and completely outsource the dynamic styling to a separate controller object flexibly instantiated via the getDefinitionByName() method. Come to think of it, you would completely shield developers from formatting and styling problems of a particular project.
Masked Input and Numeric Input
The input masking
stops a user from entering non-appropriate characters. Stricter masks
can prevent users from entering non-complete numbers, lesser than the
required text, etc. - details are always implementation-specific. Taken
to an extreme, masks can completely obliterate validation programming,
albeit at a cost of fixing a specific user experience.
The first class of this section - MaskedInput - has been created by Peter Ent from Adobe. We will be using it for illustrative purposes only; the code walkthrough of MaskedInput is beyond the scope of this article. MaskedInput is a lightweight mask in which you can indicate the maximum number of positions in the mask and prescribe the type of characters the user can type. The movement of the insertion point is controlled by the control. For example, if you set a mask for entering a U.S. phone number as (###) ###-####, in response to the end user typing 6175551212, the control will display (617) 555-1212.
Alpha keys will be blocked, but the completeness of the phone is up to the user. The control is an extension of mx.controls.TextInput and its text returns the "mask-free" data input, i.e., 61755551212, in our use case. The main controlling property of MaskedInput is inputMask, which can consist of any characters except:
- #: A single digit
- C: A letter (no digits allowed)
- c: Forces a letter to lowercase (no digits allowed)
- A or a: Allows any character.
Published November 20, 2006 Reads 58,539
Copyright © 2006 SYS-CON Media, Inc. — All Rights Reserved.
Syndicated stories and blog feeds, all rights reserved by the author.
More Stories By Victor Rasputnis
Dr. Victor Rasputnis is a Managing Principal of Farata Systems. He's responsible for providing architectural design, implementation management and mentoring to companies migrating to XML Internet technologies. He holds a PhD in computer science from the Moscow Institute of Robotics. You can reach him at vrasputnis@faratasystems.com
More Stories By Yakov Fain
Yakov Fain is a Managing Director of Farata Systems, consulting, training and product company. He has authored several Java books, dozens of technical articles. SYS-CON Books released his latest co-authored book , Rich Internet Applications with Adobe Flex and Java: Secrets of the Masters in Spring 2007. Sun Microsystems has nominated and awarded Yakov with the title Java Champion. He leads the Princeton Java Users Group. He is an Adobe Certified Flex Instructor. Currently Yakov works on the book for O'Reilly "Enterprise Application Development with Flex". He twits at twitter.com/yfain.
More Stories By Anatole Tartakovsky
Anatole Tartakovsky is a Managing Principal of Farata Systems. He's responsible for creation of frameworks and reusable components. Anatole authored number of books and articles on AJAX, XML, Internet and client-server technologies. He holds an MS in mathematics. You can reach him at atartakovsky@faratasystems.com
![]() |
CFDJ News Desk 12/17/06 11:15:01 PM EST | |||
In Part 1 (CFDJ, Vol. 8, issue 10) we introduced the destination-aware grid, formatters, and renderers. In this article we are continuing our discussion about datagrid renderers and... |
||||
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Adobe LiveCycle Enterprise Suite 2 for Cloud Computing
- Adobe Betas Target RIAs and Cloud Computing
- Adobe Cans Another 9% of its Workforce
- Moyea DVD4Web Converter V2.0 Converts DVD to FLV Fast and Synchronously with Watermarks
- Adobe & Salesforce Cut Cloud Deal
- Adobe Fiddles with its Web Apps
- Hosting.com Launches ColdFusion 9 in the Cloud
- The Real Time Infrastructure Ultimatum
- Adobe’s Aiming ColdFusion at Multiple Clouds
- Eval JavaScript in a Global Context
- Fig Leaf Software to Exhibit at Government IT Conference & Expo
- Cloud Computing Journal: Adobe to Deliver ColdFusion in the Cloud
- Is Microsoft as Free as Open Source?
- Adobe Reader Sued
- The Planet Named “Bronze Sponsor” of Cloud Computing Expo
- Microsoft Expression Web Has Got Game
- Adobe May Cooperate with Apple to Transplant Flash Player to iPhone
- Adobe Flex Developer Earns $100K in New York City
- Bruce Chizen Joins Voyager Capital as Venture Partner
- My Top Seven Wishes From Adobe MAX 2009
- The Next Programming Models, RIAs and Composite Applications
- Where Are RIA Technologies Headed in 2008?
- Constructing an Application with Flash Forms from the Ground Up
- AJAX World RIA Conference & Expo Kicks Off in New York City
- CFEclipse: The Developer's IDE, Eclipse For ColdFusion
- Personal Branding Checklist
- Adobe Flex 2: Advanced DataGrid
- Has the Technology Bounceback Begun?
- Building a Zip Code Proximity Search with ColdFusion
- i-Technology Viewpoint: We Need Not More Frameworks, But Better Programmers
- The Asynchronous CFML Gateway
- Web Services Using ColdFusion and Apache CXF






















