Debugging Flex 3 applications with Flash Player 10

I came across a problem recently when trying to debug my application after upgrading from Flash Player 9 (Debug version) to 10.2 (Debug version).  As soon as I upgraded my application stopped logging.  I searched everywhere and whilst I found a lot of people with the same problem never really found an answer.

After a lot of digging it appears to be the way you target the flash player version.  My application was targetting Flash Player 9 (in my flex-config.xml):

<target-player>9.0.124</target-player>

Changing this to 10 started the trace logging again.  As I wanted to maintain the v9 target I’ve ended up reverting back to Flash Player 9 to get the logging working again.

Advertisements

ASDoc – wading through the errors

ASDoc is a nightmare. What should have been a simple task turned into a day of trawling the net trying to find the cause of the seemingly endless errors preventing me from running it. Eventually I got it working so here’s a short post explaining the pitfalls I faced.

  • Include the Flex libraries in your -library-path argument (i.e. flex.swc, rpc.swc, framework.swc, utilities.swc). Without this I was getting errors from asdoc not being able to find some of the standard classes.
  • Check your code! Some of the errors I was getting were actually problems that just weren’t throwing errors (some of my event dispatching classes were not extending EventDispatcher, this threw lots of errors whenever asdoc encountered dispatchEvent )
  • Give your -source-path as the root of your application but use -doc-sources to list only those folders you actually want documenting

For reference here is my very simple ANT script for generating my ASDocs:


<project name="ASDoc Build Script" default="main" >

<!--
 Read in the properties file which contains the locations
 for all paths referred to here
 -->
 <property file="asdoc.properties" />

<!--
 Main Target:
 Cleans and compiles ASDocs with a log
 -->
 <target name="main" depends="clean, log, create-docs" />

<!--
 Delete and recreate the asdoc output directory
 -->
 <target name="clean" >
 <delete dir="${output.dir}" />
 <mkdir dir="${output.dir}" />
 </target>

<!--
 Run asdoc.exe on the source documents passing all required
 parameters to asdoc
 -->
 <target name="create-docs" >
 <exec executable="${asdoc.exe}" failonerror="true" >
 <arg line="-source-path '${root_src}' " />
 <arg line="-doc-sources '${framework_src}' '${actionscripts_src}' " />
 <arg line="-library-path '${irmds_library.dir}' '${flex_library.dir}'" />

<arg line="-main-title '${main.title}'" />
 <arg line="-window-title '${window.title}'" />
 <arg line="-output '${output.dir}'" />
 </exec>
 </target>

<!--
 Write out a log file
 -->
 <target name="log" >
 <record name="${output.dir}/asdoc-log.txt" action="start" append="true" />
 </target>
</project>

Applying focus to Flex application on startup

On a recent project we carried out some accessibility testing and one of the problems faced was with keyboard users who couldn’t use a mouse. After loading the application (by typing in the URL in the address bar) the users couldn’t tab to the input fields on the application, focus would never reach the flex app at all. After searching around I eventually found a little code snippet in a comment on Flex Examples.

 private function setApplicationFocus():void{
 navigateToURL(new URLRequest("javascript: document.getElementById(<DOM_ID>).focus();"), "_self");
 focusManager.setFocus();
 }
 

The above is called in the Application object on creationComplete.

RadioButton Groups and Tabbing

Making your Flex application accessible can be challenging and one of the more recent quirks I’ve encountered is the use of radio button groups.  One particular application used a number of radio button groups in the same view.  The buttons were created using Repeaters which assigned each RadioButton a group property, binding it to one of the predefined RadioButtonGroups.

This works great for mouse users but when it comes to keyboard input you’ll notice that the tabbing order is thrown out the window.  This is because Flex uses the “groupName” property of radio buttons to calculate tabbing order.  If not specified (in my case) then all radio buttons are given the same default groupName and hence tabbing can break as they are all considered one entity.  The following simple example demonstrates the fix:

 <mx:RadioButtonGroup id="radioButtonGroup1"/>
 <mx:RadioButtonGroup id="radioButtonGroup2"/>

<mx:VBox>
 <mx:RadioButton id="radioButton1"
 label="My radio button"
 group="{radioButtonGroup1}"
 groupName="Group 1"/>
 <mx:RadioButton id="radioButton2"
 label="My radio button"
 group="{radioButtonGroup1}"
 groupName="Group 1"/>
 </mx:VBox>

<mx:VBox>
 <mx:RadioButton id="radioButton3"
 label="My radio button"
 group="{radioButtonGroup2}"
 groupName="Group 2"/>
 <mx:RadioButton id="radioButton4"
 label="My radio button"
 group="{radioButtonGroup2}"
 groupName="Group 2"/>
 </mx:VBox>
 

Pesky setters

Having moved to using getters and setters to access properties of my data model (I need to perform some validation on the set and apply some logic if the conditions aren’t met) I came across a “feature” of setters which is designed to stop code executing unnecessarily.  There are many instances when I am trying to set the value of a property to what it’s currently set to (but this time the validation may deem it an invalid value).  After a lot of head scratching I finally found that when trying to do this the setter is never called.  Flex first calls the getter of the property and if the value is the same as the one you’re trying to set it will bypass the call to the setter in an effort to increase efficiency.  If this is not desired (in my case) then the following forces the setter to be called regardless:

 public function set someVariable(val:int):void {
 if (condition) {
 //some logic to alter val
 }
 else {
 //some logic to alter val
 }
 _someVariable = val;
 dispatchEvent(new Event("someVariableUpdated"));
 }

[Bindable(event="someVariableUpdated")]
 public function get speedOptionsArray():int {
 return _someVariable;
 }
 

Using PopUpManager.addPopUp from ActionScript classes

A fairly typical use case I frequently run into is the need to display some form of TitleWindow using the PopUpManager class (usually when a simple Alert won’t do the job).  This is simple when addPopUp is invoked from within a view (MXML):

 PopUpManager.addPopUp(titleWindow, this);
 

The keyword this is fine when calling from within an view as it refers to the current DisplayObject.  When calling from a pure ActionScript class however this won’t work as “this” refers to the class and not a Display Object.

Instead, to get a reference to the root application (which is normally good enough if you just want to display a simple popup) use the following:

 PopUpManager.addPopUp(titleWindow, Application.application.getChildAt(0));
 

This will add the popup to the root display object contained within the Application.