Copying objects with Flash.utils.ByteArray

July 17, 2008 by flexdream

I have been exploring the ways to copy an Array object to a new Array with less of the effort. Reason being the following statements in ActionScript

var arrayA:Array = new Array(”Jack”,”Steve”,”Mark”,”Ted”);
var arrayB:Array = arrayA;

The above statements appears to create a copy of arrayA, however in the actual it creates a new reference to the arrayA object. The problem is that if you execute any operation on arrayB object now it will impact the arrayA eventually. For example:

arrayB.pop();
trace(arrayA);

The statement is supposed to trace “Jack,Steve,Mark,Ted” whereas it will trace “Jack,Steve,Mark”.

To overcome this problem we use the following methodology

var arrayA:Array = new Array(”Jack”,”Steve”,”Mark”,”Ted”);
var arrayB:Array = new Array();
for(var i:int = 0; i < arrayA.length; i++) {
arrayB[i] = arrayA[i];

}
arrayB.pop();
trace(arrayA);

Now it will trace the desired result i.e. “Jack,Steve,Mark,Ted” and if you trace arrayB then it will trace “jack,Steve,Mark”

This methodology is very good when you are dealing with single array objects but when it comes to Nested Arrays it is really a tedious job as you have to look for every inner object of an array if it is an Array type and then again create a new array and copy it’s element. To overcome this we can use now the ByteArray class of Flash.utils package

You can review the following code used to copy an array. There is a disadvantages of using the ByteArray and that is you will loose on some speed. The ByteArray.Read method is slower than copying an Array. You can see a benchmark here

——————————–
Copying a 100000 elements array
——————————–
Copy with loops starts at :: 802504163
Copy with loop ends at :: 802504210
Time elapsed :: 47 milliseconds
Copy with ByteArray Starts at :: 802504257
Copy with Byte Array :: 802504382
Time elapsed :: 125 milliseconds

There is certainly a significant amount of processing time which ByteArray take however it is eventually helping us out when it comes to copying nested objects.

Download the fla from here.

Here is the code for the same.

——————————————————–

——————————————————–

import flash.utils.ByteArray;

var tDate:Date = new Date();
var iStartTime:uint;
var iTime:uint;
var byteArray:ByteArray = new ByteArray();

trace(”——————————–”);
trace(”Copying a 100000 elements array “);
trace(”——————————–”);
//———- Create and Populate Array ———
var arrayA:Array = new Array();
for (var i:uint; i<=100000; i++) {
arrayA.push(Math.random()*i);
if (i == 100000) {
copyArray();
}
}

//———– Copy Array using Loops ——–

function copyArray():void {
tDate = new Date();
iStartTime = tDate.time;
trace(”Copy with loops starts at :: ” + iStartTime);
var arrayB:Array = new Array();
var arr_len:uint = arrayA.length -1;
for (var i:int = 0; i <= arr_len; i++) {
arrayB[i] = arrayA[i];
if (i == arr_len) {
tDate = new Date();
iTime = tDate.time;
trace(”Copy with loop ends at :: ” + iTime);
trace(”Time elapsed :: ” + (iTime – iStartTime) + ” milliseconds”);
copyWithByteArray();
}
}
}
//——- Function copy with Byte Array ———
function copyWithByteArray():void {
tDate = new Date();
iTime = tDate.time;
trace(”Copy with ByteArray Starts at :: ” + iTime);
byteArray.writeObject(arrayA);
byteArray.position = 0;
var arrayB:Array = byteArray.readObject() as Array;
tDate = new Date();
var iByteArrTime:uint = tDate.time;
trace(”Copy with Byte Array :: ” + iByteArrTime);
trace(”Time elapsed :: ” + (iByteArrTime – iTime) + ” milliseconds”);
}

Check the Internet connectivity is present or not.

July 15, 2008 by flexdream

There are two ways to achive the same.

Method : 1)

                        private var monitor:URLMonitor;

                        public function checkConnectionStatus():void

                        {

                                var checkUrl:URLRequest = new URLRequest(“http://www.google.com“);

                                monitor = new URLMonitor(checkUrl);

monitor.addEventListener(StatusEvent.STATUS,updateConnectionStatus);

                                monitor.start();

                        }

                        public function updateConnectionStatus(event:StatusEvent):void

                        {

                                monitor.stop();

                               if(event.code == “Service.available”)

                                {

                                        Alert.show( “Online”);

                                }

                                else if(event.code == “Service.unavailable”)

                                {

                                        Alert.show(“Offline”);

                                }

                        }

Method 2) :

                       When you login to the application  , If
internet connection goes out or comes back , the below event will be
fired, you can catch this event an call    back the method described

in MEthod 1)

Application.application.addEventListener(Event.NETWORK_CHANGE,handleNetwork

Resizing button component on the fly

July 9, 2008 by flexdream

We have encountered a situation where the the UI button label was changing frequently in Flash CS3. So basis on that we have to resize our button component as the label changes. There is no inbuilt AutoResize feature in button component so what we have done is, get the size of the label and then set the width of the button. Following is the code we have implemented in this case. Put a UI button on stage and name it “_btn”. You can download the source files from here.

import flash.events.Event;
//———-
var t_arr:Array = ["This is string 1","Hello","Hello to String 3","Hello to String 4","Hello to String 5","This is a long string NOW "];
//——— Set the button textfield properties ———-
_btn.textField.autoSize = TextFieldAutoSize.LEFT; // We need to set the autosize to LEFT?RIGHT or CENTER instead of NONE
_btn.textField.multiline = false; // Make sure the multiline is false in this case to get proper dimensions
_btn.label = t_arr[0];
_btn.textField.addEventListener(Event.RENDER,resizeBtn); // Add an event listener to textfield on render event
_btn.addEventListener(MouseEvent.CLICK,clickHandler);
//——– Resize the button ———–
function resizeBtn(evt:Event):void{
// trace(evt.target.width+” “+evt.target.parent.width);
_btn.width = evt.target.width+5;
_btn.validateNow();

}
//———— Handle button click ———
function clickHandler(evt:MouseEvent):void{
_btn.label = t_arr[Math.floor(6*Math.random())];
}

Loading library assets from flash9 swf to Flex

July 9, 2008 by flexdream

This is a prototype to load external flash9 swf file into flex and using the library items from the swf. In given example we have two library symbols with linkage ids (”mc1″, “mc2″).

Just make sure when you create a movieclip from these definitions, you firstly add these to a UIComponent and then that component to stage or any container, otherwise there will be a conversion error you will be getting

You can download sources from here

Following is the code for the same.

<?xml version=”1.0″ encoding=”utf-8″?>

<mx:Application xmlns:mx=”http://www.adobe.com/2006/mxml” creationComplete=”init()” layout=”absolute”>

<mx:Script>

<![CDATA[

import mx.core.UIComponent;

//-------- Declare Variables --------

private var swfLoader:Loader;

private var fileURL:URLRequest;

//----- Initialize Function ------------

private function init():void{

//    Security.allowDomain("*");

swfLoader = new Loader();

_fileURL = new URLRequest("sample.swf");

configureListeners(swfLoader.contentLoaderInfo);

try{

swfLoader.load(_fileURL);

}

catch(e:IOErrorEvent){

trace(e.toString());

}

}

private function configureListeners(dispatcher:IEventDispatcher):void {

dispatcher.addEventListener(Event.COMPLETE, onSWFLoaded);

dispatcher.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);

dispatcher.addEventListener(Event.INIT, initHandler);

dispatcher.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

dispatcher.addEventListener(Event.OPEN, openHandler);

dispatcher.addEventListener(ProgressEvent.PROGRESS, progressHandler);

dispatcher.addEventListener(Event.UNLOAD, unLoadHandler);

}

private function completeHandler(event:Event):void {

trace("completeHandler: " + event);

}

private function httpStatusHandler(event:HTTPStatusEvent):void {

trace("httpStatusHandler: " + event);

}

private function initHandler(event:Event):void {

trace("initHandler: " + event);

}

private function ioErrorHandler(event:IOErrorEvent):void {

trace("ioErrorHandler: " + event);

}

private function openHandler(event:Event):void {

trace("openHandler: " + event);

}

private function progressHandler(event:ProgressEvent):void {

trace("progressHandler: bytesLoaded=" + event.bytesLoaded + " bytesTotal=" + event.bytesTotal);

}

private function unLoadHandler(event:Event):void {

trace("unLoadHandler: " + event);

}

//-----

private function onSWFLoaded(event:Event):void{

var mClip:Class = event.target.applicationDomain.getDefinition("mc1") as Class;

var mClip1:Class = event.target.applicationDomain.getDefinition("mc2") as Class;

var mClipInstance:MovieClip = new mClip() as MovieClip;

var mClipInstance1:MovieClip = new mClip1() as MovieClip;

//trace(mClipInstance.totalFrames);

var uiComp:UIComponent = new UIComponent();

uiComp.addChild(mClipInstance);

uiComp.addChild(mClipInstance1);

addChild(uiComp);

uiComp.x = 100;

uiComp.y = 100;

uiComp.getChildAt(0).x = 150;

}

]]>

</mx:Script>

</mx:Application>

Flex Component Life Cycle

June 29, 2008 by flexdream

The lifecycle of component in flex is certainly somewhat similar to the old V2 framework where you create a component holder, craetechildren, set-sizes and dispatch events. Following four methods plays a role for component rendering

  1. commitProperties()
  2. measure()
  3. layoutChrome()
  4. updateDisplayList()

Here is what I found after doing some studies. The most of the following part is taken from Adobe flex help however what I am trying to do here is to elaborate it more by putting up some comments to each step to make it clearer.

The green comments shows the methods and events performed by or on component itself whereas the comments in blue represents the methods and events performed on or by the parent container.

Following steps are demonstrating the Button component life cycle

  • Given if the component is going to be in a container then the parent property of component will be referred to the container(DisplayObjectContainer type)
    //– A property for UIComponent class
  • Get the style settings of the component
  • Dispatches the preinitialize event on the component.

//– The preinitialize event(mx.events.FlexEvent) is triggered when the UIComponent is in a very raw stage and there is no children in existence at that time

  • Calls the component’s createChildren() method.

createChildren is a protected method of UIComponent class which we need to override when we create a subclass of the UIComponent. Also from within an override of the createChildren() method, you call the addChild() method to add each child object.

You do not call this method directly. Flex calls the createChildren() method in response to the call to the addChild() method to add the component to its parent.

  • Calls the invalidateProperties(), invalidateSize(), and invalidateDisplayList() methods to trigger later calls to the commitProperties(), measure(), or updateDisplayList() methods during the next render event.

invalidateProperties() marks a component so that its commitProperties() method gets called during a later screen update.

invalidateSize () Marks a component so that its measure() method gets called during a later screen update.

invalidateDisplayList () Marks a component so that its updateDisplayList() method gets called during a later screen update.

The only exception to this rule is that Flex does not call the measure() method when the user sets the height and width of the component.

  • Dispatches the initialize event on the component. At this time, all of the component’s children are initialized, but the component has not been sized or processed for layout. You can use this event to perform additional processing of the component before it is laid out.

Initizlize event gets dispatched when the component has finished its construction and has all initialization properties set.

After the initialization phase, properties are processed, the component is measured, laid out, and drawn. After which the creationComplete event is dispatched.

  • Dispatches the childAdd event on the parent container.

The childAdd event is dispatched when the addChild() or addChildAt() method is called. At the time when this event is sent, the child object has been initialized, but its width and height have not yet been calculated, and the child has not been drawn on the screen. If you want to be notified when the child has been fully initialized and rendered, then register as a listener for the child’s creationComplete event.

  • Dispatches the initialize event on the parent container.

Dispatched when the component has finished its construction and has all initialization properties set. After the initialization phase, properties are processed, the component is measured, laid out, and drawn, after which the creationComplete event is dispatched.

  • During the next render event, Flex performs the following actions:
    • Calls the component’s commitProperties() method.
      commitProperties() processes the properties set on the component. You do not call this method directly. Flex calls the commitProperties() method when you use the addChild() method to add a component to a container, or when you call the invalidateProperties() method of the component. Calls to the commitProperties() method occur before calls to the measure() method. This lets you set property values that might be used by the measure() method.
    • Calls the component’s measure() method.
      Measure() calculates the default size, and optionally the default minimum size, of the component. This is an advanced method that you might override when creating a subclass of UIComponent
      .
      The default implementation of measure() sets measuredWidth, measuredHeight, measuredMinWidth, and measuredMinHeight to 0.
    • Calls the component’s (Adobe help mention this method is in UIComponent where as it is in container class) container’s layoutChrome() method.
      The
      Container class, and some subclasses of the Container class, use the layoutChrome() method to define the border area around the container.
    • Calls the component’s updateDisplayList() method.
      The updateDisplayList() method sizes and positions the children of your component based on all previous property and style settings, and draws any skins or graphic elements that the component uses. The parent container for the component determines the size of the component itself.
    • Dispatches the updateComplete event on the component.
      Dispatched when an object has had its commitProperties(), measure(), and updateDisplayList() methods called (if needed).
      This is the last opportunity to alter the component before it is displayed. All properties have been committed and the component has been measured and layed out.
  • Flex dispatches additional render events if the commitProperties(), measure(), or updateDisplayList() methods call the invalidateProperties(), invalidateSize(), or invalidateDisplayList() methods.
  • After the last render event occurs, Flex performs the following actions:
    • Makes the component visible by setting the visible property to true.
    • Dispatches the creationComplete event on the component. The component is sized and processed for layout. This event is only dispatched once when the component is created.
    • Dispatches the updateComplete event on the component. Flex dispatches additional updateComplete events whenever the layout, position, size, or other visual characteristic of the component changes and the component is updated for display.