Custom ILists, ComboBox Prompts

Following up on the last post which showed how to use custom ILists to merge two collections, this post shows how to use a custom IList to concatenate or append two collections.
Such a thing might be useful in a situation where you want to add more than one prompt to a ComboBox. In the example, I have the days of the week to choose from, but also want to add “Every Day”, “Weekdays” and “Weekends” without modifying the original days of the week collection. Of course, if you concatenate the two collections, it offsets your selectedIndex.
Download Source
Run Demo

Custom ILists, CheckBoxDataGrid, Merged Arrays

Earlier I published how to do a CheckBoxDataGrid where the selection model uses CheckBoxes instead of mouse clicks. I should have mentioned that the example used the DataGrid’s selection logic which meant that the dataprovider item’s selected state was not stored in the dataProvider and thus you couldn’t sort by whether an item was selected or not.
If you have a selected field in your data, then the code to handle checkbox selection is quite different. You basically shut down the DataGrid’s selection code and update the collection instead. You can see that in the source code for this example.
This example goes one step further, however. It assumes that you want to store selection in the dataProvider, but the dataProvider items don’t have a selected field and are “immutable”. The example code shows how to use a custom IList to merge two arrays or ArrayCollections into one merged collection where the data objects contain fields from both arrays. By doing that you can “add” a selected field to each item.
Custom ILists are a powerful way to change data without having to process each data item. The example code merges the items on-demand instead of up-front thus saving startup time. It would be wasteful to process 1000 items if you only show 7 and the user doesn’t scroll past 20.
Anyway, here’s the code. Usual caveats apply.
Download Source
Run Demo

DataGrid Double-Click To Edit

Several people have asked about changing the default editing behavior of a DataGrid so that starting an edit session requires a double-click instead of the default single-click.
Here’s my approach:
Download Source
Run Demo

Smooth Scrolling List

One of the features that got cut from 3.0 was “smooth scrolling”. List and other list-related classes scroll by row/column which can be a bit choppy at times. We tried to leave the hooks in to allow someone to do it, but we ran out of time to finish the job.
It’s too bad we didn’t finish the job as there are some difficult things to workaround in trying to get smooth scrolling to work, but I cooked this prototype up to give you a sense for how you might be able to get it working in your apps. Note that the prototype assumes that all rows are the same height. If you have variableRowHeight, that’s a whole different problem.
Usual caveats apply, and no, I don’t currently have time to make examples for TileList and DataGrid. Maybe some one else will have the time.
Download Source
Run Demo

CheckBox selection in DataGrid and List

Several folks have asked how to use Checkbox renderers to handle multiple selection in a DataGrid or List. There are some solutions out there already, but here’s mine. Usual caveats apply.
Download Source
Run Demo

Flex and ScaleMode

Flex’s underlying Flash Player has various ScaleModes that dictate how the screen should respond when the Flash ‘window’ is resized. By default, Flex apps use the NO_SCALE, which means that the screen area gets larger or smaller and can clip off the right and bottom of the screen. Flex will put up scrollbars in that case. It is the most common way applications respond to changes in screen size.
Every once in a while, someone wants to use one of the other ScaleModes which essentially magnify or reduce what you see in the Flash ‘window’. There is a trick to getting this to work correctly in Flex.
The problem is that the magnification is based on the ‘default’ size of the application. For Flex, the default size is based on the width and height attributes of the application tag. If none are specified, or percentages are used, the default is 500×375. If your applications visuals are different from that size, the magnification will look funny as the Flash Player will be trying to resize the upper 500×376 of your application into the current window size.
However, if you specify a width/height that just bounds your visuals, the HTML template generated by FlexBuilder will not allow resizing. What you have to do is choose the correct size for your application, and customize the HTML template. Here’s the recipe:
1) Create your app with the default scale mode.
2) Figure out how big the app is. In the example, I placed a label at 600,600, but it extends beyond that. One way is to just guess at numbers and see when there isn’t scrollbars or too much excess space. Otherwise, use the debugger or trace out positions and sizes on creationComplete.
3) Set the application’s width/height tags to those exact dimensions
4) Open the html-templates folder. Right-click the index.template Choose: Open with -> text editor
You’ll see this:

} else if (hasRequestedVersion) {
// if we’ve detected an acceptable version
// embed the Flash Content SWF when all tests are passed
AC_FL_RunContent(
“src”, “${swf}”,
“width”, “${width}”,
“height”, “${height}”,

Change the width/height tags back to use %:

} else if (hasRequestedVersion) {
// if we’ve detected an acceptable version
// embed the Flash Content SWF when all tests are passed
AC_FL_RunContent(
“src”, “${swf}”,
“width”, “100%”,
“height”, “100%”,

There are also other ${width} and ${height| tags for non-scripting browser that you can change as well.
5) Clean re-build
That should do it. As long as the application fully covers the size you specified, you should see the correct scale effect as you resize the window.
Example
Example Source Code
Usual caveats apply.

SelectedItem and ComboBox

Seems like it is once a month where someone is having trouble setting the selectedItem of a ComboBox. The key is that the ComboBox does an exact reference match on the items in the dataProvider. It doesnt take the time to compare values within the dataProvider items with the values in the item you are setting as the selectedItem.
In other words, if you have an array of objects:

[{ firstName: “Alex”, lastName: “Harris” }, { firstname: “Alex”, lastName: “Harui”}, {firstName: “Alex”, lastName: “Trebek”}]

you can’t just set:

selectedItem = { firstName: “Alex”, lastName: “Harui }

as that assigns the selectedItem to a different Object instance with the same values. The ComboBox class will simply look to see if there is a reference to that instance in its dataProvider, which there is not. Instead, you have to scan the dataprovider and match up values.
So many folks are doing this, that I decided to post an example so we don’t have to keep writing that scan-the-dataprovider loop. This example tries for an exact match first, so if you know you’ll never have an exact match you can save more time by cutting out that first call to super.selectedItem = value;
Source for ComboBox subclass
Test file source
Helper class source for Test file
Test file
Usual caveats apply.

Threads in Actionscript 3

Every once in a while, someone decides they would like to see threading or background processing in Actionscript. While the underlying Flash Player and Operating System use threads, the execution model for Actionscript does not.
For those who don’t know, ‘threading’ is essentially the ability to have the code do something in the background while the UI is doing something else. Because Actionscript is single-threaded, if you spend lots of time doing heavy computation, the UI cannot be updated while you’re doing that computation so your application appears stuck or effects don’t run smoothly.
Similarly, there is no yielding or blocking in Actionscript either. If the next line of code is supposed to run, you cannot prevent the next line of code from running. That means that when you call Alert.show(), the next line of code following that runs right away. In many other runtimes, the Alert window has to be closed before the next line of code continues.
Threading may be a feature of Actionscript some day, but until then, you have to live with the fact that there is no such thing right now.
In other single-threaded environments, you can get something like threads via ‘pseudo-threading’, which involves dividing up the heavy computation into small chunks on your own. (There is no solution to allow for blocking or yielding other than refactoring the application to be even-driven). Pseudo-threading is painful, but doable in most situations. Iterative tasks are easier than recursive ones, the chunk size has to be small enough to not degrade the UI response time and restoration of the execution context must be efficient otherwise you’ll spend too much time saving and restoring your state and not get anything done.
Someone asked me how I would generalize such a thing. I put this together in a couple of hours. It represents my first thoughts, not some deep thinking on the subject. A PseudoThread instance takes a callback function and a context object and calls the callback function with the context object as mahy times as it thinks it can get away with it within the frame interval. The callback function should update the context object before returning and return false when done and the PseudoThread instance dispatches an event and destroys itself.
PseudoThread.as
The following is the a test that loads an image, and adds a red tint to a copy of the image one row at a time. I purposefully slowed it down with trace statements so you can see that it doesn’t do it all at once and doesn’t seem to affect the rotating button.
PseudoThreadTest.swf
These two links are the source file and the test image.
PseudoThreadTest.mxml
the test image
The usual caveats apply (there are probably bugs, limitations, etc). Hope it helps.

HTML and Flex

In case you didn’t know, the Flash Player is not very good at displaying HTML content. Since the Flash Player is the foundation for Flex, Flex apps deployed on the Web aren’t very good at displaying HTML either. In the Adobe AIR Player, essentially a full browser is built in and HTML content is rendered faithfully. However, the amount of code required to display HTML in AIR is measured in megabytes and is too large to be included in the Flash Player download at this time.
Various folks have made reasonable attempts to get something to work in Flash. There is the DENG project . And popular among many Flex developers is the third-party HTMLComponent which uses the IFrame trick to display HTML “over” chosen areas in your Flex application. FABridge lets you integrate your Ajax application with Flex widgets.
None of these solutions are fully-integrated with Flex in the sense that the HTML is part of the Flex DOM. Right after 2.0 shipped, I was doing some testing on how fast Flash Player 9 and ActionScript 3 was and hacked together a little test which grabs an XHTML file, parses it using E4X, and creates a UIComponent for every HTML tag and one or more TextFields for every run of text. It ran suprisingly fast. I put it down to get on to Flex 3 work and poked at it a bit since then. I finally found time to fix post this code. You’ll see that there are many bugs and missing features.
To fully finish off HTML rendering and CSS, fix bugs, etc in this code is outside of the scope of Adobe’s focus at this time. It might make a great community project if some of you want to take on the effort. I’m no expert in HTML so you may or may not want to start with the code attached here. This test just proves the feasiblity of mapping HTML tags to UIComponents so there is better integration with Flex and better HTML rendering than you can currently get in the Flash Player.
Source Code for flex.html.*
Source Code for test files for flex.html.*
SWFs, HTML, etc for test files for flex.html.*
The zips can be imported into FlexBuilder 3. I didn’t post the SWFs because you need to run out of your local sandbox to get around security restrictions, so it is best to download the files, import the projects, build them and run them.
Personally, I don’t believe most of you need a full browser. You probably just have ‘plain’ HTML documents that don’t run scripts, don’t do fancy DIV stuff like wrapping text around images, etc. So you might be able to fix a few bugs and get what you want to work in relatively short order. You probably also don’t need to wade through hand-authored HTML and ‘bad’ HTML. All of that sutff adds weight to the code.
For example, htmltest3 in the test zip is test for the superscript/subscript tags. Maybe all you need is a few tags like those plus bold and italic.
The hmltest2 test also shows the principle of dynamic UI. You can send your UI over as XHTML and by wrapping your Flex component appropriately, you can generate the UI from the XHTML description. Notice the DataGrid in the document.
The code has an IHTMLElement interface so you can talk to it in DHTML/AJAX-like ways. There’s even the beginnings of an XMLHTTPRequest class. There is also a class that tries to clean up bad HTML.
Have fun, hope it helps, and DO NOT REPORT BUGS. I will probably delete all comments reporting bugs as this is totally unsupported by me.

Debugging Tricks

FlexBuilder 3 Beta 2 no longer makes both release and debug versions on every build, in order to speed up build times. This means that the debug version is no longer suffixed with -debug and it appears more than one of you used that to turn on debugging functionality w/o changing your code.
Also, a few folks have asked for a single line of code that could be pasted verbatim into function bodies that would report the name of the function, and a few others have wondered if there is a way to get the name of the calling function.
Assuming you are using a debugger player, the source code at this link demonstrates how to do each of these things. See setDebugFlag(), getFunctionName() and getCallingFunctionName().
Download file

private function setDebugFlag():void
{
var e:Error = new Error();
var s:String = e.getStackTrace();
// trace(s);
var i:int = s.indexOf("setDebugFlag");
if (s.charAt(i + 14) == '[')
debugMode = true;
}
[Bindable]
public var debugMode:Boolean = false;
private function getFunctionName(e:Error):String
{
var s:String = e.getStackTrace();
var i:int = s.indexOf("at ");
var j:int = s.indexOf("()");
return s.substring(i + 3, j);
}
private function getCallingFunctionName(e:Error):String
{
var s:String = e.getStackTrace();
// trace(s);
var i:int = s.indexOf("at ");
i = s.indexOf("at ", i + 3);
if (i == -1)
return "caller unknown";
var j:int = s.indexOf("()", i + 3);
return s.substring(i + 3, j);
}

where the latter two functions are can be used like this:

private function doSomething():void
{
trace(getFunctionName(new Error()));
doit();
}
private function doSomethingElse():void
{
trace(getFunctionName(new Error()));
doit();
}
private function doit():void
{
trace(getFunctionName(new Error()));
trace("   called by", getCallingFunctionName(new Error()));
}

Usual caveats apply, and the numbers and strings might have to be adjusted for different languages.