October 2008 Archives

From Java to Flex In (n + 1) Easy Steps

| 2 Comments
Much has been made about ActionScript 3 (AS3) being a fully mature object-oriented language on par with older languages like Java, C++ or SmallTalk. I can't say that I agree, but I can attest to the many syntactical similarities between Java and AS3. Those similarities can be very misleading, though, since they can make you unwary of fundamental differences bwtween the two languages.

Here are a few key differences between JAva and AS3 that I have discovered:

Flex Object Equality

In Java, developers quickly learn the difference between the "==" operator and a call to an object's equals() method. In Flex, there are two equality operators, "==" (normal equals) and "===" (memory address equals). When dealing with primitives, things are pretty straight forward. If, however, you are dealing with more complex objects, you may want to consider using the built-in object comparator method ObjectUtil.compare().

Have a look here for more details: http://danielroop.com/blog/2007/09/02/actionscript-30-object-equality/

Variable "Block" Scoping in Flex

In Java, the location where a variable is declared makes it easy to determine the scope within which that variable will be visible. If a variable is declared within a for block, for instance, that variable is invisible once you get past the curly bracket at the end of the for loop. Not so in Flex. Variables within a block are visible to all of the function within which they are declared, even outside of the block they are in.

Therefore: do not re-use variable names in a given Flex function or you will eventually get burned.

Useful reference: http://marxsoftware.blogspot.com/2008/10/no-block-scope-in-actionscript.html

Cast Operator

In Flex, casting an object to a Class type is done using the "as" operator.

var someVar:ClassTypeA = new ClassTypeA();
var someOtherVar:ClassTypeB;
someOtherVar = someVar as ClassTypeB;

Flex equivalent to Java instanceof operator

Flex's equivalent to the Java "instanceof" operator is the "is" operator. As far as I know (which isn't saying much), it seems to behave the same as its Java counterpart.

if (someVar is ClassTypeA) {
    trace("someVar is an instance of a ClassTypeA.");
}

// Assuming that the cast succeeds
if (someVar as ClassTypeB is ClassTypeB) {
    trace("This should always be true.");
}

That's pretty much all that comes to mind for the time being, but there's surely more to come later. Please feel free to add your own Java/Flex differences in the comments section.

Something you might not have known about filtered DataGrids

| No Comments
Well, it's been a while since I've posted anything on here. The blog VM was down... seems somebody wanted to plug the toaster and coffee maker in at the same time. But I digress...

The Set Up

Part of the tool we're developing requires that subsets of data from a single ArrayCollection be displayed in different DataGrids across multiple screens, some of them on the same screen at the same time. My implementation involves derived ArrayCollections that are populated from the single collection and are accessed through getters. In order to keep all of these DataGrids synchronized with the contents of the "parent" collection, I ended up jumping through some event-handling hoops (basically listen for change events on the parent collection and reset the dataProvider for the individual DataGrids when it happens). Because this approach may make maintenance a little more work down the road, Brad sent along a bit of example code that he found showing another way to feed a single ArrayCollection into multiple DataGrids on the same screen.

Here it is:
ArrayFilter2DataGrids.mxml

The Test

At first glance, the efficiency of the solution seemed less than optimal: the "parent" collection would have to be traversed completely twice to generate each sub-collection (once to copy it and once to filter the elements on display.) In order to verify this assumption, I added counters to each of the filters. In doing so, I discovered something very puzzling about how filters are fired, more specifically, about how often ArrayCollection filter functions are fired when used with a DataGrid.

The Result

Using the above application as-is (plus the counter code), I found that each of the filters was run 3 x the number of elements in the parent collection. In other words, with 3 filters and a collection of 5 elements, just displaying the page caused 45 (3x3x5) filter function calls! Keep in mind that I was expecting 15 calls. With a little more experimentation, I determined that the actual number of filter calls for a DataGrid is determined as follows:

  # of elements in the parent collection
X # of nested components outside the DataGrid

In other words, it turns out that how often a filter function is called depends on how deeply the DataGrid is nested within parent Components. By adding a Canvas around the three DataGrids, the number of filter function calls rose by 15 (3x5).

I guess you learn something every day...

Moral of the story

- Don't put a lot of code into your filter functions if they'll be used in conjunction with a DataGrid because you have no control over how often they will be called.
- ArrayCollection filterFunctions may be handy and fairly elegant, but roll your own filtering if you want to keep the number of calls to a minimum.

Here is the test version of the code that counts the calls to the filter functions:
MultiListGridViewer.mxml

Hopefully this little write-up will prove useful/informative to somebody. I know that I was very surprised at the inefficiency involved, but chalk it up to the designer's assumption that filter functions won't individually cost a lot in terms of performance. But then again, you know what they say about assuming...


Taylor





About this Archive

This page is an archive of entries from October 2008 listed from newest to oldest.

September 2008 is the previous archive.

November 2008 is the next archive.

Find recent content on the main index or look in the archives to find all content.