Archive for the ‘Flex’ Category

Variable scope in ActionScript Flex

Monday, March 8th, 2010

Hoisting, the strangest ActionScript/Flex “feature” I’ve ever seen (at the moment of writing). Probably you’ve never heard of hoisting. I was hinted to this feature when I had two variables with the same name in one function. Flex was warning about this, but I didn’t really understand why.

Check the following example:

private function existsInSources(searchFor:String):Boolean {
	if(searchFor.length > 10) {
		for each(var valueObj:Object in longStringsCollection) {
			if(valueObj.key == searchFor) {
				return true;
			}
		}
	} else {
		for each(var valueObj:Object in shortStringsCollection) {
			if(valueObj.key == searchFor) {
				return true;
			}
		}
	}
	return false;
}

By default Flex will give the following warning at the second declaration of valueObj, line 9:

3596: Duplicate variable definition.

Coming from other program languages this will (should) strike you as odd behaviour. Both variables ‘valueObj’ exist in their own scope… right?
Not in ActionScript, ActionScript has “Hoisting”.
From adobe.com:

An interesting implication of the lack of block-level scope is that you can read or write to a variable before it is declared, as long as it is declared before the function ends. This is because of a technique called hoisting, which means that the compiler moves all variable declarations to the top of the function.

So basically, the code from the example is transformed to:

private function existsInSources(searchFor:String):Boolean {
	var valueObj:Object;
	var valueObj:Object;
	if(searchFor.length > 10) {
		for each(valueObj in longStringsCollection) {
			if(valueObj.key == searchFor) {
				return true;
			}
		}
	} else {
		for each(valueObj in shortStringsCollection) {
			if(valueObj.key == searchFor) {
				return true;
			}
		}
	}
	return false;
}

“It just shows a warning and doesn’t have any impact on that beautiful piece of code you wrote there, so who gives a ….”.

The problem lies in the fact that this “feature” also means you can refer to objects before they are even initialized.

if(myString.length > 20) {
	trace('Length is over 20!');
} else {
	trace('Length is 20 or smaller');
}
var myString:String = "Hello world!";

Result: a runtime error.

Cannot access a property or method of a null object reference.

Flex compiles (yes, this code compiles fine…) this to:

var myString:String;
if(myString.length > 10) {
	trace('Length is over 10!');
} else {
	trace('Length is 10 or smaller');
}
myString = "Hello world!";

Pay attention to your variable scope, especially when using Flex/ActionScript.

Setting width and height in Flex using CSS

Saturday, May 9th, 2009

In the current version of Flex (3) it’s not possible to set width and height using CSS. The application I’m working on has a lot of screens containing a lot of TextInput fields. I want to be able to control the width and height of these text fields using CSS.

Sean Christmann has a nice solution for this. He uses HBox, I’ll use TextInput as an example:

package com.yourpackage {

	import mx.controls.TextInput;
	import mx.styles.StyleManager;

	public class ExtTextInput extends TextInput {

		public function ExtTextInput():void {
			super();
			// Default styleName for this component
			this.styleName = "extTextInput";
		}

		/**
		 * This method makes styles "width", "height", "percentWidth", "percentHeight", "x", "y" and "visible"
		 * valid from css.
		 */
		override public function styleChanged(styleProp:String):void{
			super.styleChanged(styleProp);
			if(!styleProp || styleProp == "styleName"){
				//if runtime css swap or direct change of stylename
				var classSelector:Object = StyleManager.getStyleDeclaration("." + styleName);
				if(classSelector != null){
					applyProperties(classSelector, ["width", "height", "percentWidth", "percentHeight", "x", "y", "visible"]);
				}
			}
		}

		private function applyProperties(styleObj:Object, arr:Array):void{
			for each (var item:String in arr){
				var prop:Object = styleObj.getStyle(item);
				if(prop != null) this[item] = prop;
			}
		}

	}
}

As the implementation extends the standard TextInput it will behave just like the standard TextInput. Databinding, runtime style changes… it all works.

The code sets a default styleName for the component, the style could look like this:

.extTextInput {
	percentWidth: 100;
	height: 18;
}

Of course you can set a different styleName while declaring the component in your application.

Installing Flex Builder on Ubuntu 9.04

Saturday, April 11th, 2009

For my work I’ve been working with Adobe Flex. If you’re doing Flex development you (probably) work with Flex Builder. It has features a development tool should provide; code completion, design view, good integrated building/running of projects, debugging etc.

At work I’m tied to my Windows XP laptop, at home I work with Ubuntu Linux. Whenever I do Flex development in private time, I always use the Windows machine… but what if you’d like to develop Flex on Linux?

Google quickly pointed to Flex Builder Linux. ‘Yey! A Linux Flex builder!’ The release notes shows some (minor) inconveniences:

Unsupported Flex Builder Features

  • Design view
  • States view
  • Refactoring
  • Data Wizards
  • Cold Fusion – Data Services Wizard
  • Web Services introspection
  • Profiler

And some known issues:

  • Organize Imports removes necessary imports
  • The default version of Java installed in Ubuntu systems is GCJ. This is not supported by the Flex Builder Linux installer and the installation may fail on Ubuntu Systems. Please ensure you have an installed Sun JRE before installing Flex Builder Linux.
  • Getting a transparent window for AIR App depends on your Linux distro capabilities. You may need to turn-on some settings (ex: Desktop effects on Ubuntu 7.10) or install some special packages (example: compiz-fusion, beryl for installing compositing manager) to get this working (if its not working by default)

I left out anything not related to Ubuntu or Flex Builder in general. Besides the ‘design view’ most issues are minor issues. Usually the ‘design view’ is used for some initial drag and drop interface building or for containers with and ‘absolute’ layout  (i.e. Canvas). The ‘design view’ then limits the build/run/change cycles.

Installing Flex Builder on Ubuntu 9.04

The prerequisites mentioned by Adobe are

  • Eclipse 3.3.x (32-bit)
  • Sun JRE 1.5.x or newer (32-bit)
  • Firefox 1.0, 1.5, or 2.0 (32-bit)

At the moment of writing, the version of Eclipse provided with Ubuntu is 3.2.x. So you’ll have to get a newer Eclipse version from Eclipse.org. I tried the latest version available, which is 3.4.2 (which later turned out to be a bad idea, use a 3.3.x version). Installation of Eclipse is as easy as unpacking to the desired location, so I’m not describing that any further. Make sure you have the Sun JRE 1.5.x or newer installed. I installed ’sun-java6-jdk’ via the package manager, the JDK includes the JRE. Configure Eclipse to use that.

JRE settings Eclipse

JRE settings Eclipse

Download the Flex Builder Plugin for Linux.

Installing Flex Builder Linux

To install Flex Builder Linux:

  1. Prior to installing, remove any previous versions of Flex Builder Linux. Refer to the section ‘Uninstalling Flex Builder Linux’ below for instructions.
  2. Run the installer either marking it as executable (chmod +x) or by using a shell to execute it (sh FlexBuilder_Linux_Plugin.bin).
  3. Accept the license agreement and follow the prompts.
  4. When prompted, specify whether to install Flash Player 9 (note that this is an updated version of Flash Player 9 and that Flex Builder Linux will work with earlier versions of Flash Player 9 for Linux). This is the debug version of Flash Player 9, which is required for debugging support and exception display.
  5. Follow the prompts to complete the installation.
  6. Start Eclipse.
    Note: You must create a new workspace before beginning. Select File > Switch Workspace from the menu bar and enter a new folder name. If the folder doesn’t exist, Eclipse creates it.

Install Folder

Install Folder

When choosing the ‘install folder’ you can leave that to default, the Eclipse folder will be defined in the next window.

Eclipse Folder

Eclipse Folder

As described select the Eclipse folder, it must contain a subfolder named ‘configuration’. Continue the installation untill the installer displays that you’re done.

Start Eclipse and open the Flex perspective. If you get the following error while opening a MXML file:

Could not open the editor: Assertion failed:  org.eclipse.jface.util.Assert$AssertionFailedException: Assertion failed

Make sure you have the correct Eclipse version, I used 3.3.2 on Ubuntu 9.04.

Flex Builder Linux

Flex Builder in Linux with code completion

It seems Flex Builder accepts Flex 3 license keys, which is then ignored as it still displays “Flex Builder Linux will expire in xxx days.” If you use charting you can enter your license to remove the trial message.

You already choose to use the trail period and didn’t enter your license key? Open ‘license.properties’ in  ‘home/username/.adobe/Flex’. And add:

flexbuilder3=yourlicensekey

Or change:

flexbuilder3.displayedFirstLaunchMessage=true

to:

flexbuilder3.displayedFirstLaunchMessage=false

Restart Flex Builder and enter your license key in the launch message.