Flex Gotchas

On the whole, one of the aspects I like most about Flex is that it generally works the way you expect it to. That being said there are definitely certain things which don’t quite work as expected.

Corner Radius

This is actually what inspired me to write this post. I’m a fan of rounded rectangles (add a vertical gradient and a drop shadow and you’ve got a classic Web 2.0 look). I’d expect this to do the trick.

<mx:Box backgroundColor="#888888" cornerRadius="8"/>

However, to make it work you need to set the borderStyle property

<mx:Box backgroundColor="#888888" cornerRadius="8" borderStyle="solid"/>

Hand Cursor

A similar example is when trying to show a hand cursor. I’d expect this to work.

<mx:Label text="test" useHandCursor="true"/>

However, you need to use the following

<mx:Label text="test" useHandCursor="true" buttonMode="true" mouseChildren="false"/>

SWF Caching

This is more of a Firefox bug, however if you rely on the browser to handle caching the SWF (and updating when a new SWF is created) you’ll run into problems in Firefox. The best solution I’ve found so far is to convert the html wrapper file into a PHP script (any scripting language should do). You can then add the following to the SWF name.

?checksum=<? echo md5_file("__SWF_file_name__") ?>

Binding

I’ve written about this before but it’s caused me enough trouble that it’s worth repeating. If there are null errors inside of a function used in binding the Flash player will swallow them. It needs to do that as binding expression will often have null errors (ie, if you bind to person.name and person isn’t yet set). However, this can be very confusing.

Copying Objects

A really useful function is ObjectUtil.copy(), it will make a deep copy of your object. However, in order to use it you need to first register any classes which your object is composed of. Here’s the code I use.

for each (var classRef:Class in [ Class1, Class2, etc... ])
{
	var className:String = getQualifiedClassName( new classRef()) ;
	registerClassAlias( className, classRef );
}

Flex AutoComplete: Version 1.1

It’s been well over a year since I released the 1.0 version of the component. Since then I’ve received countless emails/comments with feature requests and bug reports. This new release addresses all of the major issues.

Latest version

Here’s what’s new:

  • Full support for Flex 4: The component now supports Flex 4 100%. The demo has been rebuilt using the Flex 4 SDK
  • Added allowEditingSelectedItems property: You can now enable making changes to items once they’re selected.
  • Added delimiter property: When allowing the user to select multiple items you can now specify which character to use as the delimiter.
  • Added clearSearchOnFocusOut property: This enables specifying whether the search text should be cleared on focus out
  • Added clear method: Makes clearing the selection much simpler
  • Better overall usability

In addition, I’ve also fixed a number of critical bugs:

  • Fixed problems when binding to the AutoComplete’s values
  • Fixed issue where setting selectedItem multiple times would fail
  • Fixed problem where allowDuplicates didn’t works for objects
  • Resolved issues when using with Validators
  • Improved garbage collection performance
  • Resolved issues when using an XMLListCollection as the dataProvider
  • Does a better job handling invalid data
  • Fixed issues related to using the tabIndex property
  • Other bug fixes and tweaks..

Best,
Hillel

Come hear me speak in Tel Aviv

I’ll be speaking at Flash and Flex Israel on Sunday, April 25th.

Here’s the blurb for my presentation

Flex in the Trenches – This session will cover a variety of topics to help you transition from a beginner/intermediate Flex programmer to an advanced one. Topics will include resolving common performance issues, making your apps look pretty, effective use of the Flex DataGrid/ItemRenderers, getting compilation times down, plus more…

Mihai Corlan, a Platform Evangelist with Adobe will also be speaking. His blog has an excellent list of Flex frameworks and libraries which is definitely worth checking out.

Best,
Hillel

Flex Builder Shortcuts

I find that good keyboard shortcuts can save me a ton of time. Here are some of my favorites for Flex Builder (note: these can all be customized in the preferences).

  • F11: Debug last launched
  • Ctrl + Shift + R: Open Resource
  • Ctrl + O: Quick Outline
  • Ctrl + F7: Next View
  • Ctrl + F8: Next Perspective
  • Ctrl + Shift + L: Key Assist

Hope you find these useful,
Hillel

Flex Tip: Two really useful tools

I was just introduced to two incredibly useful tools.

FlexPMD helps to improve code quality by auditing any AS3/Flex source directory and detecting common bad practices.

fxSpy allow you to inspect and dynamically change most properties and styles of the visual components in your Flex application. You can – for example – try out a specific width or a background color for your component before changing it in your code.

If you haven’t yet seen them I highly recommend checking them out.

Best,
Hillel

Import, Export, Copy & Paste Flex DataGrid

In addition to searching, two common features implemented in DataGrids are import/export and copy/paste. There are a number of great solutions already out there. The purpose of this post is to show how we can bring them together (along with some additional code/tweaks) to provide the user with a DataGrid which plays nicely with their favorite spreadsheet application.

Overview of demo

  • There are three ways to copy the selected items from the left DataGrid: using the “Copy” button, pressing Ctrl+C or right clicking and then selecting “Copy Item(s)”.
  • The copied data is stored in tab separated format, when pasting it into a spreadsheet it will retain its column structure.
  • To paste data into the right DataGrid give it the focus by clicking on it and then press Ctrl+V.
  • Click “Import” to upload either a CSV (comma sperated) or TSV (tab separated) file.
  • Click “Export” to generate a CSV file of the data in the DataGrid.

Import/Export

In Flex 3, in order to upload a file you need a small script on the server (in Flex 4/Flash 10 the client is able to handle this locally). Included in the source you’ll find two PHP files: csvImport.php and csvExport.php. To support exporting the data from the DataGrid I’m leveraging a nice algorithm written by Sasa Radovanovic explained in this post.

This solution is meant to work with plain text csv and tsv files, if you need to support Excel (.xls) files I’d recommend checking out as3xls.

Copy/Paste

One of the limitations of the Flash Player is that (for security reasons) we’re unable to access data from the user’s clipboard. This makes pasting rather tricky. Manish Jethani has documented a clever solution in this post where he uses a hidden text field to allow the user to paste data into a DataGrid.

Field Mapper

This component provides the user with a way to map the columns in the data to the properties of the objects. It will attempt to determine if the first row of the data looks like it should be a header row and will then try to automatically map the fields.

Hope you find this useful,
Hillel

Resource Bundles in Flex (new thoughts on the topic)

This is the follow up to a post I wrote a little while ago.

Eliminate the Metadata tag

In the past I was accessing the resource bundle directly in the class. This meant that in I had to add the Metadata tag in every file. A better approach is to create a static class which calls ResourceManager.getInstance(). This way only this class needs to have the Metadata for the bundles. Here’s the static class I’m using.

package 
{
	import mx.resources.ResourceManager;
	
	[ResourceBundle("People")]
	[ResourceBundle("Groups")]
	[ResourceBundle("Framework")]
	public class ResourceUtils
	{
		public static function getString( module:String, key:String, failSilently:Boolean = false ):String
		{
			var value:String = ResourceManager.getInstance().getString( module, key );
			
			if (!value)
			{
				value = ResourceManager.getInstance().getString( "Framework", key );				
			}
			
			if (!value && !failSilently)
			{
				throw new Error( "Error: failed to find value for " + key + " in " + bundleName + " resource bundle" );
			}
			
			return value ? value : "";
		}
	}
}

The application that I’m working on is divided into a number of modules, each has their own resource file. To support this, when requesting a string you also specify the module. If the value isn’t found in the module resource file, then we check the overall framework resource file.

Throw an error if a value isn’t found

I find that I pretty often mistype a key for a string. The default behavior in Flex is to return null, I prefer throw an error in this case as it makes tracking down any missing values much easier. I’ve added the failSilently flag for cases where they may not be a value.

Here’s an example of how you’d use it

<mx:Label text="{ ResourceUtils.getString( Consts.MODULE_PEOPLE, 'addButton' ) }"/>

Static classes for resources in general

This idea of using static classes to reference resources also works well for images. I just saw this in a book I’m reading AdvancED Flex Application Development. It’s a nice, clean approach.

package
{
	[Bindable]
	public class AssetLib
	{
		[Embed(source="buttonUpSkin.png")]
		public static var buttonUpImage:Class;

		[Embed(source="buttonDownSkin.png")]
		public static var buttonDownImage:Class;
	}
}

Hope you find this useful,
Hillel

Flex AutoComplete: Version 1.0

It’s been about a year since first creating the component. I’ve been using it extensively in the applications I work on and it’s been downloaded thousands of times. At this point I’m pretty confident in saying that it works reliably.

Latest version

If you’re already using the component you probably noticed that there’s now a “Latest version” link (rather than the old Demo and Download links). I’ve decided to set up a permanent page on my blog for the component. The important info (ie, the component’s license) is currently scattered amongst the past posts, this way I can keep everything together in one place.

Here’s what’s changed in this release

  • Added support for XMLListCollections: You can now use either an ArrayCollection or an XMLListCollection as the dataProvider.
  • ListBuilder is now a first class component: I’ve refactored the code to support using the ListBuilder on it’s own.
  • Added browserFilterFunction: I’ve added a browserFilterFunction which enables applying a separate filter which is applied to the results shown in the browser. I sometimes show a mix of items in the component. I use this to offer multiple browse options in the actionMenu in the AdvancedAutoComplete.
  • Bug fixes and tweaks: As always, I’ve gone through all of the comments and fixed any issues people have found.

Thanks to e/o who’s spotted bugs, suggested improvements and just been supportive in getting the component to this state. There’s no doubt in my mind that sharing the component with the Flex community has made it far better than it otherwise would have been.

Best,
Hillel

Flex Issue: Using “Copy” as label for ContextMenu item

It looks like Flex won’t allow you to use “Copy” as the label of a ContextMenu item. If you try to do so, no error is generated but the menu item isn’t added to the menu. I spent way too long trying to figure out why my code wasn’t working, hopefully this saves you the trouble.

Update: As per the comment below by JabbyPanda, here’s the full list of restricted words.

Best,
Hillel