December 13th, 2007 by Kyle
Posted in: Flex

Adobe Flex sdk beta 3 and Adobe AIR beta 3 just release to Adobe Labs yesterday, so I have updated my version checker AIR application to detect the new SDK and also compiled the app against the new AIR classes targeting the new AIR runtime.

All other blog references will be pointing to this new version >>>> here <<<<<.


No Comments »

December 12th, 2007 by Kyle
Posted in: Flex

This isn’t as difficult as some may think. Basically your itemRenderer opens up a popup. When the renderer creates the popup, it sets an “opener” property on the popup pointing back to “this”, which is the itemRenderer. That way, when the editing is finished in the popup, the popup can pass data back to a function in the itemRenderer to do the update, close itself, and set focus back to the itemRenderer.

Here is the code for the app:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*" >
    <mx:Array id="arr">
        <mx:Object articleName="Finding out a characters Unicode character code Downloading the latest Adobe Labs version of Flex 3 SDK/Flex Builder 3 (codename: Moxie)" data="15" />
        <mx:Object articleName="Setting an icon in an Alert control" data="14" />
        <mx:Object articleName="Setting an icon in a Button control" data="13" />
        <mx:Object articleName="Installing the latest nightly Flex 3 SDK build into Flex Builder 3" data="10" />
        <mx:Object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:Object articleName="Using the Alert control Formatting data tips in a Slide" data="8" />
    </mx:Array>
    <mx:ArrayCollection id="AC" source="{arr}" />     

    <mx:DataGrid height="250" dataProvider="{AC}" variableRowHeight="true" width="60%" editable="true">
        <mx:columns>
            <mx:DataGridColumn dataField="data" headerText="ID" editable="false" width="125"/>
            <mx:DataGridColumn
                editable="false" wordWrap="true"
                headerText="Article Name"              
                itemRenderer="MyRenderer" dataField="articleName"/>
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
 

Read the rest of this post»


No Comments »

December 11th, 2007 by Kyle
Posted in: Flex

I had a customer asking how to do this.
Sorting the datagrid sorts the underlying dataprovider.
Remember that things like ArrayCollections are just essentially views of the data. So adding an element to the underlying data, regardless of the position at which you add the new item, will not affect its position in the “view”. It will get added in its sorted position if the view is showing sorted data. The workaround to this is show in the simple sample below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="init()">
    <mx:Script>
        <![CDATA[
            import mx.collections.ArrayCollection;
                   
            public var objs:ArrayCollection = new ArrayCollection();               
            /*
             * initialize the dataprovider
             */

            private function init():void {
   
                var obj:Object = new Object();
                obj.name = "carry";
                objs.addItem(obj);
               
                obj = new Object();
                obj.name = "fred";
                objs.addItem(obj);
               
                obj = new Object();
                obj.name = "henry";
                objs.addItem(obj);
               
                obj = new Object();
                obj.name = "issac";
                objs.addItem(obj);
                           
                obj = new Object();
                obj.name = "mary";
                objs.addItem(obj);
               
                obj = new Object();
                obj.name = "tom";
                objs.addItem(obj);
               
                obj = new Object();
                obj.name = "tom2";
                objs.addItem(obj);
                                                                               
                dg.dataProvider = objs; 
            }
           
            import flash.utils.ByteArray;
           
            private function clone(source:Object):*
            {
                var myBA:ByteArray = new ByteArray();
                myBA.writeObject(source);
                myBA.position = 0;
                return(myBA.readObject());
            }

            private function addObj():void{

                var temp:Array = clone(objs.toArray());
                objs=new ArrayCollection(temp)
                dg.dataProvider=objs;

                var obj:Object = new Object();
                obj.name=‘’;
                objs.addItemAt(obj, 0)
       
            }
           
        ]]>
    </mx:Script>
    <mx:Button width="150" label="Add New Row" click="addObj()" />             
    <mx:DataGrid id="dg" editable="true" width="50%" height="80%">
    <mx:columns>
        <mx:DataGridColumn headerText="Name" dataField="name"
            editable="true" />
    </mx:columns>
</mx:DataGrid>                         
   
</mx:Application>
 

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9


No Comments »

December 7th, 2007 by Kyle
Posted in: Flex

I have seen a few people and had a customer ask how to detect when a flex app loses focus.
Here is a sample app that shows the technique and a practical application of this functionality.
When you click and drag a DividedBox separator, if you move the mouse outside the Flex application window, the app should realize this and “drop” the separator at that horizontal or vertical position (depending on the orientation of your divider). It doesn’t do this automatically (and maybe is should), but it is easily done and demonstrates the technique that can be used for other reasons.

Here is the simple app:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="addListeners(event)">
    <mx:Script>
        <![CDATA[
            private var lastX:Number;
            private var lastY:Number;         
           
            private function addListeners(event:Event):void{
                systemManager.stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
                systemManager.stage.addEventListener(Event.DEACTIVATE,deactivate);
                systemManager.stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMove);        
            }
           
            private function removeListeners(event:Event):void{
                systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, mouseLeave);
                systemManager.stage.removeEventListener(flash.events.Event.DEACTIVATE,deactivate);
                systemManager.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mouseMove);                       
            }

            private function mouseMove(event:MouseEvent):void{
                //trace("move…"); 
                lastX=event.stageX;
                lastY=event.stageY;
            }         
           
            private function mouseLeave(event:Event):void{
                //trace("left");
                removeListeners(event);
                dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP,true,false,lastX,lastY))
            }
            private function deactivate(event:Event):void{
                //trace("deactivate");
                removeListeners(event);
                dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP,true,false,lastX,lastY))
            }
           
        ]]>
    </mx:Script>

    <mx:VDividedBox id="div1" dividerPress="addListeners(event)" dividerRelease="removeListeners(event)">
        <mx:VBox height="200" width="300" borderStyle="outset">
            <mx:Button label="Something"/>   
        </mx:VBox>
        <mx:VBox height="200" width="300" borderStyle="outset">
            <mx:TextArea width="100%"/>
        </mx:VBox >
    </mx:VDividedBox>
</mx:Application>
 

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9


No Comments »

December 5th, 2007 by Kyle
Posted in: Flex, actionscript, mxml

XML and ampersands do not mix well.
Flex uses mxml which is XML.
This can lead to issues when writing binding expressions in mxml tags for component properties when you are trying to write logical expressions using ‘and’.

Here is a simple sample that demonstrates how to escape the ampersands in the expression and how to create a logical expression that does not even use ‘and’, but achieves the same result.

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
   
    <mx:Script>
        <![CDATA[
            [Bindable]
            public var bOne:Boolean=false;
            [Bindable]
            public var bTwo:Boolean=false;     
        ]]>
    </mx:Script>
   
    <mx:Button label="(click to toggle) bOne: {bOne}" click="bOne=!bOne"/>
    <mx:Button label="(click to toggle) bTwo: {bTwo}" click="bTwo=!bTwo"/>
   
    <mx:Label text="If bOne and bTwo are true, the buttons below will be Enabled"/>
    <!–escape the ampersands for the logical and operator –>
    <mx:Button label="enabled?" enabled="{(bOne && bTwo)}"/>
    <!–or use this compounded logical statement which will evaluate to the same thing –>
    <mx:Button label="enabled?" enabled="{(bOne ? bTwo : false)}"/> 
   
</mx:Application>
 

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9


No Comments »

November 26th, 2007 by Kyle
Posted in: Flex, Flex Builder, Flex Data Services

I just recently was made aware that there are actually 3 different “builds” of Flex SDK “hotfix 3″ out there.
1. Originally hotfix 3 was applied to hotfix 2 (updating a few swcs) - version 1
2. Late summer 2007 it was realized this confused some folks so the hotfix kb article was replaced with a full version of the SDK with the fixes applied - version 2
3. Flex Builder 3 beta 2 shipped with the latest/greatest SDK from the 2.0.1 branch which is an equivalent to hotfix 3 SDK - version 3.

These versions should be functionally identical afaik.

I updated my version checker to detect and differentiate these versions. I have updated the original blog entry here and also have links to the update AIR app here.


No Comments »

November 26th, 2007 by Kyle
Posted in: Flex

This is a follow on to my previous blog entry:
http://blog.739saintlouis.com/2007/11/22/flex-linebreaks-in-the-datagrid/

Here I show how to deal with line breaks in itemRenderer and itemEditors instead of in a datagrid labelFunction.
(This is also a nice example of writing simple, separate itemRenderer and itemEditors.)

Here is the application code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:local="*">

    <mx:Array id="arr2">
        <mx:Object articleName="Finding out a characters \nUnicode character code \nDownloading the latest Adobe Labs version \nof Flex 3 SDK/Flex Builder 3 \n(codename: Moxie)" data="15" />
        <mx:Object articleName="Setting an icon in an Alert control" data="14" />
        <mx:Object articleName="Setting an icon in a Button control" data="13" />
        <mx:Object articleName="Installing the latest nightly \nFlex 3 SDK build into Flex Builder 3" data="10" />
        <mx:Object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:Object articleName="Using the Alert control\nFormatting data tips in a Slide\n" data="8" />
        <mx:Object articleName="Finding out a characters \nUnicode character code \nDownloading the latest Adobe Labs version \nof Flex 3 SDK/Flex Builder 3 \n(codename: Moxie)" data="15" />
        <mx:Object articleName="Setting an icon in an Alert control" data="14" />
        <mx:Object articleName="Setting an icon in a Button control" data="13" />
        <mx:Object articleName="Installing the latest nightly \nFlex 3 SDK build into Flex Builder 3" data="10" />
        <mx:Object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:Object articleName="Using the Alert control\nFormatting data tips in a Slide\n" data="8" />
        <mx:Object articleName="Finding out a characters \nUnicode character code \nDownloading the latest Adobe Labs version \nof Flex 3 SDK/Flex Builder 3 \n(codename: Moxie)" data="15" />
        <mx:Object articleName="Setting an icon in an Alert control" data="14" />
        <mx:Object articleName="Setting an icon in a Button control" data="13" />
        <mx:Object articleName="Installing the latest nightly \nFlex 3 SDK build into Flex Builder 3" data="10" />
        <mx:Object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:Object articleName="Using the Alert control\nFormatting data tips in a Slide\n" data="8" />       
    </mx:Array>
    <mx:ArrayCollection id="arrColl2" source="{arr2}" />     

    <mx:DataGrid height="250" dataProvider="{arrColl2}" variableRowHeight="true" width="60%" editable="true">
        <mx:columns>
            <mx:DataGridColumn
                headerText="Name of the article in question"                
                itemRenderer="MyRenderer" dataField="articleName"
                itemEditor="MyEditor" editable="true"
                editorUsesEnterKey="true" />
            <mx:DataGridColumn dataField="data" headerText="ID of the article" editable="false"/>
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
 

Here is the itemRenderer based on Text:

<?xml version="1.0" encoding="utf-8"?>
<mx:Text xmlns:mx="http://www.adobe.com/2006/mxml" text="{txt}"
    implements="mx.controls.listClasses.IDropInListItemRenderer">
<mx:Script>
    <![CDATA[
        import mx.controls.listClasses.ListData;
        import mx.controls.dataGridClasses.DataGridListData;
        import mx.controls.listClasses.BaseListData;

        private var _listData:DataGridListData;          
   
        [Bindable]
        public var txt:String;

        override public function set data(value:Object):void {
            super.data = value;   
            var str:String = data[_listData.dataField];
            var myPattern:RegExp = /\\n/g; 
            var newStr:String=str.replace(myPattern, "\n");
            txt = newStr;
        }

        override public function get data():Object {
            return super.data;
        }           
       
     override public function get listData():BaseListData
        {
            return _listData;
        }
   
        override public function set listData(value:BaseListData):void
        {
            _listData = DataGridListData(value);
        }   
   
    ]]>
    </mx:Script>
</mx:Text> 
 

Here is the itemEditor based on TextArea:

<?xml version="1.0" encoding="utf-8"?>
<mx:TextArea xmlns:mx="http://www.adobe.com/2006/mxml" text="{txt}"
    implements="mx.controls.listClasses.IDropInListItemRenderer">
<mx:Script>
    <![CDATA[
        import mx.controls.listClasses.ListData;
        import mx.controls.dataGridClasses.DataGridListData;
        import mx.controls.listClasses.BaseListData;

        private var _listData:DataGridListData;          
   
        [Bindable]
        public var txt:String;

        override public function set data(value:Object):void {
            super.data = value;   
            var str:String = data[_listData.dataField];
            var myPattern:RegExp = /\\n/g; 
            var newStr:String=str.replace(myPattern, "\n");
            txt = newStr;
        }

        override public function get data():Object {
            return super.data;
        }           
       
     override public function get listData():BaseListData
        {
            return _listData;
        }
   
        override public function set listData(value:BaseListData):void
        {
            _listData = DataGridListData(value);
        }   
   
    ]]>
    </mx:Script>
</mx:TextArea>
 

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9


No Comments »

November 22nd, 2007 by Kyle
Posted in: Flex

This is a follow up to my previous linebreak post.

This demonstrates how to deal with parsing linebreaks when they are in the text data for a datagrid.
You can either escape them in your source text data as shown in the previous post or you can use a labelFunction and some simple regular expression parsing to handle the escaping.

Here is the application code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
   
    <mx:Script>
        <![CDATA[
        private function format(item:Object, column:DataGridColumn):String{
            var str:String=item[column.dataField].toString();
            var myPattern:RegExp = /\\n/g; 
            var newStr:String=str.replace(myPattern, "\n");
            return newStr;
        }
        ]]>
    </mx:Script>
   
    <mx:Array id="arr1">
        <mx:Object articleName="Finding out a characters \nUnicode character \ncode" data="15" />
        <mx:Object articleName="Setting an icon in an Alert control" data="14" />
        <mx:Object articleName="Setting an icon in a Button control" data="13" />
        <mx:Object articleName="Installing the latest nightly \nFlex 3 SDK build into Flex Builder 3" data="10" />
        <mx:Object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:Object articleName="Using the Alert control" data="8" />
        <mx:Object articleName="Formatting data tips in a Slider" data="7" />
        <mx:Object articleName="Downloading the latest Adobe Labs version of Flex 3 SDK/Flex Builder 3 (codename: Moxie)" data="6" />
    </mx:Array>
    <mx:ArrayCollection id="arrColl" source="{arr1}" />   
    <mx:Array id="arr2">
        <mx:Object articleName="Finding out a characters {’\n‘}Unicode character code" data="15" />
        <mx:Object articleName="Setting an icon in an Alert control" data="14" />
        <mx:Object articleName="Setting an icon in a Button control" data="13" />
        <mx:Object articleName="Installing the latest nightly {’\n‘}Flex 3 SDK build into Flex Builder 3" data="10" />
        <mx:Object articleName="Detecting which button a user pressed to dismiss an Alert dialog" data="9" />
        <mx:Object articleName="Using the Alert control" data="8" />
        <mx:Object articleName="Formatting data tips in a Slider" data="7" />
        <mx:Object articleName="Downloading the latest Adobe Labs version of Flex 3 SDK/Flex Builder 3 (codename: Moxie)" data="6" />
    </mx:Array>
    <mx:ArrayCollection id="arrColl2" source="{arr2}" />     

    <mx:Text text="this dg uses a labelFunction to manipulate the linebreaks"/>

    <mx:DataGrid id="dataGrid" dataProvider="{arrColl}" variableRowHeight="true" width="60%" height="35%">
        <mx:columns>
            <mx:DataGridColumn labelFunction="format" dataField="articleName" headerText="Name of the article in question"/>
            <mx:DataGridColumn dataField="data" headerText="ID of the article" />
        </mx:columns>
    </mx:DataGrid>   

    <mx:Text text="this dg has the linebreaks modified in the source {’\n‘}arraycollection using curly braces and single quotes."/>

    <mx:DataGrid dataProvider="{arrColl2}" variableRowHeight="true" width="60%" height="35%">
        <mx:columns>
            <mx:DataGridColumn dataField="articleName" headerText="Name of the article in question"/>
            <mx:DataGridColumn dataField="data" headerText="ID of the article" />
        </mx:columns>
    </mx:DataGrid>
</mx:Application>
 

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9


No Comments »

November 19th, 2007 by Kyle
Posted in: Flex, actionscript, mxml

I had a customer who was having problems with linebreaks in her Flex code.
I had used linebreaks before with no problem until I realized that she was setting text with linebreaks in mxml and not setting properties dynamically as I had done in all instances in teh past when dealing with linebreaks.
I search the Adobe public bugbase and found this bug:

http://bugs.adobe.com/jira/browse/SDK-12649

I thought I’d write a simple app to demonstrate the problem and workarounds.

Here is the source for the app:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
    <mx:Label id="ta1" height="75" width="250" text="This does not \nwrap"/>
    <mx:Button label="click to set via actionscript" click="ta2.text=’Setting via actionscript and\nthis does wrap’"/>
    <mx:Label id="ta2" height="75" width="250"/>
    <mx:Label id="ta3" height="75" width="250" text="Alternatively with this workaround,{’\n‘}this wraps too"/>
</mx:Application>
 

Browse the source of this example.
Download a zipfile containing the source to this sample.

This movie requires Flash Player 9


No Comments »

November 15th, 2007 by Kyle
Posted in: Flex

Here is a sample demonstrating how to dynamically create tabs but maintain the currently selected tab.

Application:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
    xmlns:tabNavigatorTest="tabNavigatorTest.*">

    <mx:Script>
        <![CDATA[
            import mx.core.Container;
           
            private function setTabSelectedIndex(selectedIndex:Number = 0):void{
                trace("before selected index = " + myTab.selectedIndex);
                myTab.selectedIndex = selectedIndex;
                trace("after selected index = " + myTab.selectedIndex);
            }
           
            private function resetTabChildren():void{

                myTab.removeAllChildren();
                addIndex.maximum=0;
                addChildToTabAtIndex(0,0);       
                addChildToTabAtIndex(1,1);
                addChildToTabAtIndex(2,2);               
                               
            }
       
            private function addChildToTabAtIndex(childType:int,index:int):void{
                var childToAdd:Object;
                switch(childType){
                    case 0 :    childToAdd = new Page1();
                                break;
                    case 1 :    childToAdd = new Page2();
                                break;
                    case 2 :    childToAdd = new Page3();
                                break;
                }
                myTab.addChildAt(childToAdd as DisplayObject,index);
                addIndex.maximum++;;               
            }         
           
        ]]>
    </mx:Script>
    <mx:VBox width="100%" height="100%">
        <mx:HBox>
            <!– adjust selectedindex.value - 1 to account for 0 based index –>       
            <mx:Button click="setTabSelectedIndex(tabSelectedIndex.value-1)" label="Set tab selected index"/>
            <mx:NumericStepper id="tabSelectedIndex" minimum="1" maximum="3" value="1"/>
            <!– adjust selectedindex.value - 1 to account for 0 based index –>
            <mx:Button click="addChildToTabAtIndex(tabSelectedIndex.value-1,addIndex.value-1 )">
                <mx:label><![CDATA[<-add tab child Page Type - at position->]]></mx:label>
            </mx:Button>
            <mx:NumericStepper id="addIndex" minimum="1" maximum="1" value="1"/>                       
        </mx:HBox>
   
        <mx:TabNavigator id="myTab" creationComplete="resetTabChildren()"
                width="100%" height="100%" creationPolicy="all" backgroundColor="#FFFFFF"
                borderThickness="1" borderStyle="solid" minHeight="0" minWidth="0"
                selectedTabTextStyleName="selectdTab"
                >
        </mx:TabNavigator>
        <mx:Button click="setTabSelectedIndex(0);callLater(resetTabChildren)" label=