Author Archive: Alex Harui

Apache Flex Presentations at 360Flex 2012 in Denver

I had the honor of giving two presentations on Apache Flex at 360Flex in Denver. One was part of the keynote and focused on things everybody should know about Apache Flex, and the other was more focused on those planning to contribute to the code in the project.

These files are actually pptx files but I had to give them .zip suffixes in order to post them.

Keynote Presentation

Apache Flex Session

Spark Menu and MenuBar for Flex 4.5

A few folks pointed out that the Menu and MenuBar prototypes I put together based on Spark List are not working in Flex 4.5. I found enough time to try to get it working again. I also added support for a MenuBar item that doesn’t have a menu.

Run Demo

Download Source

Catching UncaughtError in Flex Modules

A common issue amongst those building Flex Applications that use Flex Modules is that the UncaughtError capability of Flash Player 10.1 does not work for Modules. This is due to the fact that Modules dereference the module SWF’s loaderInfo right away, in order to make unloading modules automatic. In other words, as soon as you dereference the last instance of classes in the module, the SWF can be garbage collected. If Flex did not dereference the loaderInfo, the developer would have to keep track of what instances of module classes have been created and whether they are still around, and only if they are all gone would you dereference the loaderInfo.

It turns out that the UncaughtError mechanism relies on having loaderInfo references so the module subsystem in currently incompatible with UncaughtErrors. The Flash Player engineers are testing out a fix where the main application becomes the fallback for any UncaughtErrors that have not been caught and cancelled. For now, though, I figured out a way to hook directly to the module’s loaderInfo and listen to UncaughtErrorEvents there. That will allow you to get UncaughtErrors from the module. The key is in the timing. By the time the ModuleEvent.READY fires, it is too late, the loaderInfo has been dereferenced and is null. During ProgressEvents, the loaderInfo may not be available. But fortunately, at the time of ModuleEvent.SETUP, you can grab the loaderInfo and listen for UncaughtErrorEvents.

Here are some relevant snippets of code. Let’s say you have an application with an UncaughtErrorEvent handler like this:


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
layout="vertical"
initialize="init()">

<fx:Script>
<![CDATA[
import mx.events.ModuleEvent;

private function init():void
{
systemManager.loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,
uncaughtErrorHandler);
}

private function uncaughtErrorHandler(event:UncaughtErrorEvent):void
{
trace("caught uncaught error");
event.preventDefault();
}

]]>
</fx:Script>

<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>

<mx:ModuleLoader id="moduleLoader" url="GEHFlexModule.swf" width="200" height="150" />
</mx:Application>

In this app, the uncaughtErrorHandler will get UncaughtErrors from every other point of the application except for the module loaded by the ModuleLoader. To get the UncaughtErrors from the module, all you have to do is add a ModuleEvent.SETUP event handler:


<mx:ModuleLoader id="moduleLoader" url="GEHFlexModule.swf" width="200" height="150" setup="setup(event)" />

and use the setup event to hook up the uncaughtErrorHandler to UncaughtErrors from the module.


private function setup(event:ModuleEvent):void
{
DisplayObject(event.module.factory).loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR,
uncaughtErrorHandler);
}

Hope that helps.

Migratory Foul: Performance Problems Migrating From Flex 3.x To Flex 4.x

Some folks migrating 3.x projects to 4.x have run into noticeable
performance degradation, especially if they are using the default skins that
ship with each SDK. This article attempts to explain why and propose
alternative implementations.

The main reason for the difference is that the the default skins/theme for
4.x is Spark and the default skins/theme for 3.x is Halo. Spark skins are
simply not as fast as the Halo skins. The Halo skins are written as highly
optimized ActionScript and are based on a lightweight Flex class called
ProgrammaticSkin. And partly because of those optimizations, the way you
would write or modify a skin for a MX Button could be drastically different
than the way you’d write a skin for MX DataGrid or MX ComboBox.

In Spark, we wanted a consistent approach to writing every skin. And we
wanted interoperability with the MX components. For reasons like that, the
Spark skins are based on a Skin class that in turn is based on UIComponent.
That instantly makes your skin heavier and slower than a Halo skin. Then,
we wanted every skin to be written in MXML so that the tools can more easily
understand the parts of the skin and assist in the modification and
development of a skin. Most folks know that MXML tends to be slower than
ActionScript, but we chose MXML to enable non-programming designers to be
involved in the skinning workflow without those designers having to worry
about mucking up a bunch of ActionScript code.

The cost per-skin of this extra weight is on the order of a few milliseconds
per skin, but it adds up. A recent test case was putting 250 checkboxes on
the screen. A somewhat unrealistic case since it is hard to cram 250
checkboxes on a screen and make it usable, but it took another 500ms in the
debugger player so the developer noticed right away when he went from 3.x
with Halo to 4.x with Spark. Even if the goal was 100 checkboxes, the extra
200ms would cause some animation to freeze noticeably.

Now, if you are migrating a 3.x project for which you have already written
your own custom theme based on ProgrammaticSkin and you are going to use the
same theme in 4.x, you shouldn’t see problems of this magnitude. It really
has only been an issue when you were using the Halo theme and you now try to
use an MXML-based theme like Spark. So what should you do? Consider not
using MXML-based themes for now. We are looking at ways to optimize an
MXML-based skin hopefully in time for our 2012 releases so hopefully this is
just a short-term issue. We must admit, though, that it is enough of an
issue that the mobile theme for the new mobile components in Flex 4.5 are
written in ActionScript and not in MXML, and that’s why we’re working on
MXML skin performance post-Flex 4.5.

You have choices: You can only swap in ActionScript-based skins for a few
components, or swap in a whole theme. Just replacing the Spark MXML
checkbox skin with the Halo checkbox skin (but leaving the Application and
other skins as MXML-based Spark skins) made a huge difference in performance
since the majority of work was in those 250 checkbox skins that were being
drawn.

Another new capability of Flex 4.x that can cause noticeable performance
degradation when compared to a 3.x application is what we call Advanced CSS.
In Flex 4 we support more CSS selector types but they require more
processing and less caching. If you create enough components in one chunk,
you might notice the extra time spent. We are looking at optimizations
post-Flex 4.5 as well. You can turn off Advanced CSS by setting the
compiler’s compatibility-version flag to 3, but that turns off lots of other
things as well and makes it harder to incrementally add or swap in Spark
components.

It is possible to subclass components and turn off Advanced CSS
for entire classes of components. The following link shows how I turned off
Advanced CSS in a subclass of CheckBox.
Download Sample Source

In analyzing these test cases, it became apparent that the “natural” way to
build up display object “trees” in ActionScript is not the most optimal in
terms of performance. Lots of folks dynamically create dialogs and other
sub-sections of their UI via code like this:


var loginUI:VBox = new VBox();
var loginText:TextInput = new TextInput();
loginUI.addChild(loginText);
var loginButton:Button = new Button();
loginUI.addChild(loginButton);
app.addChild(loginUI);

It turns out this is terribly inefficient compared to this almost identical
code:


var loginUI:VBox = new VBox();
app.addChild(loginUI);
var loginText:TextInput = new TextInput();
loginUI.addChild(loginText);
var loginButton:Button = new Button();
loginUI.addChild(loginButton);

All I did was addChild the outer container before adding its children. In
other words, it is faster to parent the parent before parenting the
children. Why? Because the CSS style calculations that involve inheriting
styles cannot be calculated until you have a parent. So in the first
example, when adding the TextInput and Button to the Vbox, a bunch of
temporary work gets done that gets tossed and re-done when the Vbox is
finally added to the child. If you use the second pattern, the CSS style
calculations don’t have to do any temporary, throw-away, work. It turns out
if you look at the code generated for an MXML file, you’ll see that parents
are parented before parenting their children. In the 250 checkbox cases,
the code was using the first pattern. By changing it to the second pattern
(and using the Halo theme) the test case on 4.x actually runs faster than
the 3.x test case. Yes, if the same optimization had been done on the 3.x
test case then 3.x would still be faster, but there is less degradation for
the second pattern because that is the common MXML-generated path and some
work was done to optimize it. Another new feature of 4.x is per-module
styles and the overhead of that capability (which had the main benefit of
greatly reducing probability that modules will get stuck in memory) carries
less penalty if you parent the parent first.

Remember that the underlying Flash Player is a deferred renderer. Adding an
empty Vbox to the app first won’t cause it to show up on the screen until
the rest of the code finishes running so there is no danger of flicker or
other visual artifacts.

In conclusion, if you are seeing performance degradation when migrating from
3.x to 4.x, and it is related to these topics in this article, then it was a
decided trade-off we made to involve designers in the development process
and produce better user experiences, or provide more CSS capabilities, or
reduce the chance memory leaks. But you can choose to use ActionScript
skins, do some subclassing to turn off Advanced CSS on components that are
created often, and build your dynamic UI more optimally and reduce the
degradation or in some cases, get even better performance than what you had
experienced in 3.x.

Spark Checkbox DataGrid With Drag and Drop Support

The Spark DataGrid is almost ready to ship. We ran out of time to do some of the things MX DataGrid could do, including popular things like drag and drop of columns to change the order of the columns, and drag and drop of items to copy or move items to and from other DataGrids and Lists or within the same DataGrid.

I found some time to show how to add that to the DataGrid. I was able to do it without subclassing, which indicates that we got the public APIs right, but if you want to have multiple DataGrids in your app, I would fold the drag/drop code into a subclass anyway. In the demo, there is an empty list below the DataGrid you can drag to or drop from.

If you’re wondering why we couldn’t bake this into DataGrid even though I had time to code it up on my blog, it is because of the time required to test and debug and handle drag/drop of cell selection. It is a prototype, not finished code. But I’ll bet we’ll integrate code like this into a future release.

I also created the Spark version of the CheckBox in MX DataGrid post. I like this implementation of using CheckBoxes in DataGrid when the dataProvider doesn’t have a slot to store the selected state. You can use the selectedIndices or selectedItems to access which items are checked without having to loop through your dataProvider. In creating this post, I also created the Spark version of the tri-state CheckBox (a CheckBox with a partially filled check box that indicates that not all items are selected in the DataGrid. It was pretty easy to do because the skin parts are easily accessible and it is easy to add a new state to the CheckBox.

Usual caveats apply: not officially supported, may not fix bugs, etc.

Run Demo
Download Source

Spark DataGrid Footers

Here is a first attempt at putting footers in a Spark DataGrid.  The approach taken is to customize the skin and add an additional Grid element and assign it an custom ArrayList that contains the summary data. A subclass of GridColumn allows specifying a summary function. In the demo, the first column does a sum, the second does an average.

One of the surprises was in the partAdded handler.  Because you can’t control the order in which skin parts are added in subclasses, you have to build in some redundancy when there are interdependencies between skin parts.

Run Demo
Download Source

Usual caveats apply.

Spark DataGrid with HierarchicalCollection and GroupingCollection

A Spark-based DataGrid is one of the most important additions to Flex. It will be officially released shortly with the Flex 4.5 SDK. Finally, folks will be able to use the same skinning workflows they use on their other Spark components to customize the look of the DataGrids in their applications.

Unlike the MX DataGrid, where I wrote most of the code, and like the MX AdvancedDataGrid, where I didn’t write any of the code, I don’t think I wrote a single line of code for Spark DataGrid. A completely different team of folks wrote it. And that means I’m not all that familiar with how it works under-the-hood, so I decided to try learn more about it by stretching its capabilities in order to see if it has the right APIs and extension points, by adding a capability that won’t ship in-the-box with Flex 4.5, and that is the ability to use GroupingCollection to get some sort of hierarchical (tree-like) display in the Spark DataGrid.

It took about 4 hours to get to this point. I started with the example in the Flex doc at this link. Spark DataGrid only takes data providers that implement mx.collections.IList, so I wrote an ICollectionView to IList adapter, plugged it in, wrote a custom renderer and it pretty much works. Links to Demo and Source below. I’d say if I can do something like this in half a day, that the APIs and extension points are in good shape.

Note: Like all Flex 4.5 applications, the newly released Flash Player 10.2 is required to run the demo. The blog software we use makes it impossible to upload HTML wrappers so there isn’t any wrapper around the demo that will force the upgrade of the Flash Player. The Flex 4.5 prerelease will install the player or you can get it from the adobe site here.

Usual caveats apply. This code is not officially supported nor is it thoroughly tested.

Run Demo
Download Flash Builder 4.5 Project

MX DataGrid, List and VariableRowHeight

This issue seems to come up frequently:  Someone wants to use a renderer that has a flow-based component like mx:Text or the new Spark Label or Spark RichEditableText and wants the rows to be of variable heights.  Trouble ensues.

There is a key aspect of the MX item renderer lifecycle that has to be accounted for in these scenarios, and that is that, before a renderer is measured, the host List or DataGrid will set the explicitWidth of the renderer to the width of the list or the datagrid column.  This is important since the renderer’s measuredHeight is dependent on the width of the flow-based text components.  If this isn’t handled correctly, the renderer may clip text and/or make it impossible to calculate the exact size of the List or DataGrid.

This also implies that using percent width in a renderer won’t help as percentWidth isn’t applied until after measurement.  You have to tie the width of any flow-based component to the explicitWidth of the renderer so that the measuredHeight is reported correctly.  Sometimes that will require overriding the measure() method, but often you can just use data-binding.

Here  is an example of a custom flow-based renderer.  It draws a square in the upper-left corner and then flows text to the right of it onto multiple lines.  I use data-binding in this example to set the width of the mx:Text so it will then report its measuredHeight correctly.  That allows me to figure out the exact height of the DataGrid by calling measureHeightOfItems and factoring in the viewMetrics.

Run Example
Download Source

Flex and Embedded Fonts

Flex tries to provide you with the most flexible way of using embedded fonts in your applications. If your application consists of just one SWF and you embed fonts in that SWF, everything should just work, but once there are multiple SWFs involved, while it should work most of the time, if it doesn’t, you may need the following information to figure out why. With Flex 4 defaulting to using RSLs, your default configuration now involves multiple SWFs and many more of you are suddenly using multiple-SWF applications because each RSL counts as a SWF.
The principle rule is that there are two places that the Flash Player will look to find an embedded font to use to display text in a TextField or TextLine. It will look in the global table where fonts are registered via Font.registerFont, and it will look in the SWF whose code instantiated the TextField or TextLine.
Font.registerFont has a couple of limitations. One is that, if two SWFs try to register the same font, the last one in wins. That is normally ok until you start embedding font subsets (only certain characters in the font) which you might want to do when optimizing for SWF size, especially with large Asian fonts. If SWF A has only upper case characters and SWF B has only lower case characters, for example, then SWF A won’t be able to display its characters if SWF B loads later and registers its font of lower case characters.
The second limitation is that there is no Font.unregisterFont call so registering a Font pins the SWF with the font in memory.
For those reasons, Flex never tries to call Font.registerFont. Instead it has an infrastructure that tries to make sure that all TextFields and TextLines are created by code in the SWF that contains the embedded font. We use the term “SWF context” to mean the SWF whose code created the TextField or TextLine. And because a TextField or TextLine can have only one SWF context, it means that all fonts displayed in a TextField or TextLine must be embedded in the same SWF. If you must mix, you will have to register the font and deal with the fact that the SWFs containing the fonts may never unload.
Making sure the right code instantiates TextField is a bit trickier than it first seems. You can’t just put calls to “new TextField” or “TextBlock.createTextLine()” in a single factory class and link that class into every SWF. The ApplicationDomain rules may cause the class in a SWF to be ignored (see the modules presentation on the blog for details).
For example, suppose I create a TextLineFactory class and link it into SWF A and SWF B. If SWF A loads SWF B, when B calls TextLineFactory, it will be calling the one in SWF A and thus the TextLine will be created in a different SWF context than B expected and the embedded fonts won’t show up. Or suppose the TextLineFactory class is in an RSL. Then it is not in SWF A or SWF B so those SWFs won’t be able to display text using fonts embedded in those SWFs.
In order to solve this, Flex adds code to a uniquely named class in every SWF it generates for RSLs and Applications and Modules. That way there are no ApplicationDomain class collisions. Flex does that by adding that code to the main class of every SWF and names it after the SWF. For example, if you have A.SWF with mx:Application, Flex wraps the mx:Application with a SystemManager subclass called something like A_SystemManager and adds factory APIs to that subclass.
For TextField, Flex uses the ISystemManager.create() method. For TextLine, Flex uses the ISWFContext.callInContext API. If you are writing your own text-based components, it would be a good idea to subclass the Flex components so you can inherit the embedded font infrastructure that makes those calls and also figures out the next hard part: given an embedded font, which SWF do you reference to call these APIs? Again, because of ApplicationDomain rules, any class you write may be running in a different SWF context from the caller.
Flex tracks all fonts it embeds in SWFs and each SWF registers its embedded fonts in the EmbeddedFontRegistry on load. (Yes, we do it in a way that allows the SWF to unload). When a Flex text component is about to display text, it looks up the fontFamily, fontStyle and fontWeight and sees if there is an embedded font in the registry that matches, biasing the search to the current SWF so that colliding subsets will work. The EmbeddedFontRegistry returns the best SWF context for that font and the component uses that SWF context to create the TextField or TextLines. That means that even simple components like Label will destroy and create a new children if the font styles change since the style change could require the use of a different SWF context.
How can Flex always know which SWF is the current SWF given the ApplicationDomain rules? This is done in Flex by conditionally propagating the moduleFactory property to child components. All top-level components in a SWF have their moduleFactory set to the SWF’s IModuleFactory and propagate it to children unless the child already has a moduleFactory set.
Note that even though SystemManager is an IModuleFactory, not all ISystemManagers are IModuleFactory like AIR’s WindowedSystemManager so code should not assume that you can determine your SWF context from the systemManager property.
There are lots of implications from having this infrastructure. If you can’t control the code that creates the TextLine or TextField because the instances are created via mx.core.IFactory (itemRenderers and Chart visuals), you may need to use ContextualClassFactory or code up something similar. It also means you can’t cache a single TextField for measuring text; you may have to cache a TextField in each SWF context. It means that SystemManager.isFontEmbedded and Font.enumerateFonts may not know about every font that has been loaded and return inaccurate results.
And, it turns out that other font-related APIs must also be called in the correct SWF context. If you call ElementFormat.getFontMetrics(), you must also call that via ISWFContext if you are using embedded fonts in a multi-SWF configuration. Getting this wrong an result in really subtle bugs like having the position of strikethrough and underline being off by a pixel or two, or having baselinePosition be off by a pixel or two.
The Flex team has put a lot of work into making all of this transparent to developers, so hopefully you won’t ever need to know all of this, but folks definitely get tripped up by this now and then. And now, if you do, I hope you can use the information in this post to solve your problem.

Spark Charts

MX Charts are very flexible and use composition much like the Spark architecture. I don’t know if/when we’ll create Charts on the Spark base classes. I decided to see how far I could get by putting a bunch of DataGroups and a custom collection and layout into play.
Usual caveats apply. There are bugs, missing features, etc. But it might be a starting point if you need to throw some charts on the screen on top of the Spark.
Run Demo
Download Source