Handling doubleclick on Flex components

Handling a common event like a double click is not so simple as we may assume when it comes to Flex programming.
In fact there are several critical aspects related to this event, first of all we have to set the attribute doubleClickEnabled to true in order to make our components double clickable, and this sounds pretty silly to me. Why should I enable an object to receive an event which is so common and “natural”? This is incoherent from a software design perspective end totally unexpected by the user. Anyway this is not a real problem, because once we know about it we have just to use a setter, but double click is somehow buggy in the framework and its broadcasting can be blocked mysteriously when using certain components. I faced this issue by trying to handle a double click on a DataGrid which makes use of custom item renderers and I tested that by double clicking on the “special cells” (those rendered by my own renderers) the MouseEvent.DOUBLE_CLICK is not dispatched/cacthed. To solve the problem I had to draw an invisible rectangle using the underlying Actionscript graphics API! This is my workaround:

this.graphics.beginFill(0xffffff, 0);
this.graphics.drawRect(0, 0, this.parent.width, this.parent.height);

Finally, it seems that double click is completely ignored by Firefox 3.6 on Mac OS X, but fortunately this seems to been fixed in the last release (3.6.3)

Get hours, minutes and seconds from a number without maths operations

Today I’m gonna show you a secret ninja technique to extract hours, minutes and seconds from a number (representing an amount of seconds). In my example I will show an Actionscript code, but this can be implemented in JavaScript and maybe other languages too.
So, the scenario is the following: we have a number representing seconds and we want to know how many hours this amount of seconds contains, how many minutes and how many remaining seconds. We know that a minute is composed by 60 seconds and an hour by 60 minutes and we could write a series of maths operations in order to accomplish our objective, but there is a way far simple and fast: use the Date class!
Date class already implements all the methods we need:

  • getHours()
  • getMinutes()
  • getSeconds()

So, in order to take advantage of these useful methods, all we have to do is initialize a “fake” date using the amount of seconds we want to “split” into hours, minutes and seconds. The Date class has several OPTIONAL arguments that can be specified during its initializations, these are:

  • year
  • month
  • date (day number)
  • hours
  • minutes
  • seconds
  • milliseconds

Because theme all are optional, we can create a date object by specifying only the know arguments (in our case seconds) and by assigning null or zero to the others:

var date:Date = new Date(null, null, null, 0, 0, 9137);

Then by calling getHours, getMinutes and getSeconds we will obtain what we expect:

trace("hours: ", date.getHours()); // 2 hours
trace("minutes: ", date.getMinutes()); // 32 minutes
trace("seconds: ", date.getSeconds()); // 17 seconds

Not sure about the result? Let’s test it:

60 * 60 * 2 = 7200; (seconds contained in 2 hours)
32 * 60 = 1920; (seconds contained in 32 minutes)
7200 + 1920 + 17 = 9137; (original seconds!)

AIR applications logging… my own extension to Flex’s logging framework

Finally it’s time to release my little project and my first personal and public Actionscript library.
What I’m talking about? I realized a little “subframework” which goal is to extend Flex’s logging framework, in order to write log messages to files on the disk and provide a custom Flex’s UI component (which can be easy used into every AIR application) to read/filtering these log files.

Learn more here: http://www.daveoncode.com/air-logging-framework

Just a note: although I tested the library (windows and mac) and it works fine, this project may contains bugs or doesn’t work under some circumstances. Comments and feedback are welcome!

ArrayCollection: filterFuntion with multiple filter functions using decorator pattern

I was looking for an elegant solution to implement multiple filter functions on an ArrayCollection (which provides a method filterFunction() that can be assigned dynamically in order to filter data inside the collection). The first and only valid solution I found was that one from Cristian Rotundu, he has extended ArrayCollection class providing a filterFunctions properties which accepts an Array of functions which will be executed in sequence (into a loop) once filterFunction is triggered. Anyway I didn’t want to subclass ArrayCollection and by using the decorator pattern I implemented my own multiple filters version.

So, this is what I done:

  1. I defined an interface IFilter, which declares only one method: apply()
  2. I defined a dummy Filter class (which implements IFilter in a basic way just to agree to the interface), that is used as a basic empty filter to decorate. It also has a constant called ALL_VALUES which is used as a wildcard for filters (it’s a simple string with value “*”, which means “all values are allowed”)
  3. I defined an abstract AbstractFilterDecorator class
  4. I created as many subclass of AbstractFilterDecorator as the filters I need (yes I treat filters as classes not mere functions)

The implementation code is the following:

var data:ArrayCollection = ArrayCollection(grid.dataProvider);
var filter:IFilter = new Filter();
filter = new LevelFilter(filter, levelValue);
filter = new CategoryFilter(filter, categoryValue);
filter = new DateFilter(filter, dateValue, "DD/MM/YY");
data.filterFunction = filter.apply;

The filter object is wrapped by decorators which all accepts 2 common arguments: an IFilter reference and an Object representing a value. The DateFilter has a third parameter which is used to configure an internal DateFormatter (from mx.formatters package).
I’m pretty satisfied :)
Uh… and if you are worried about performance, it is fast enough because filter object are created once and then the function assigned to filterFunction is a reference to the resulting decorated filter.

I realized a very simple example application which can be downloaded here.
This following is the content of the mxml file:

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

			import mx.collections.ArrayCollection;
			import com.daveoncode.filters.*;
			private function applyFilters():void {
				var data:ArrayCollection  = ArrayCollection(userGrid.dataProvider);
				var filter:IFilter = new Filter();
				filter = new AgeFilter(filter, ageFilterValue.text);
				filter = new DateFilter(filter, dateFilterValue.selectedDate);
				filter = new SexFilter(filter, sexFilterValue.value);
				data.filterFunction = filter.apply;
	<mx:Panel title="Filters" width="600">
			<mx:FormItem label="Age:">
				<mx:TextInput id="ageFilterValue" width="30" />
			<mx:FormItem label="Sex:">
				<mx:ComboBox id="sexFilterValue" dataProvider="{[{data: Filter.ALL_VALUES, label: 'ALL'}, {data: 'm', label: 'Male'}, {data: 'f', label: 'Female'}]}" />
			<mx:FormItem label="Join date:">
				<mx:DateField id="dateFilterValue" formatString="DD/MM/YY" />
				<mx:Button label="Apply filters" click="{this.applyFilters()}" />
	<mx:Panel title="Users" width="600">
		<mx:DataGrid id="userGrid" width="100%">
						<mx:Object age="24" sex="f" name="Susan" joinDate="{new Date(2007, 5, 15)}" />
						<mx:Object age="36" sex="f" name="Ashley" joinDate="{new Date(1998, 7, 20)}" />
						<mx:Object age="24" sex="f" name="Jennifer" joinDate="{new Date(2001, 3, 24)}" />
						<mx:Object age="19" sex="f" name="Emma" joinDate="{new Date(2002, 3, 24)}" />
						<mx:Object age="44" sex="f" name="Carol" joinDate="{new Date(1999, 9, 16)}" />
						<mx:Object age="28" sex="m" name="Peter" joinDate="{new Date(2005, 3, 12)}" />
						<mx:Object age="35" sex="m" name="Mike" joinDate="{new Date(2008, 10, 10)}" />
						<mx:Object age="26" sex="m" name="Dave" joinDate="{new Date(2008, 10, 10)}" />
						<mx:Object age="44" sex="m" name="William" joinDate="{new Date(2004, 9, 16)}" />
						<mx:Object age="24" sex="m" name="Sean" joinDate="{new Date(2006, 3, 24)}" />