Sunday, 5 of February of 2012

News

Use flash based animation in Flex and control it.

Few days ago, I was stuck in a weird problem.

The problem was:

Need an animation that need to be controlled by itself as well through flex.
Actually I had to use the flash cs3 actionscript3 based animation into my flex 4 based application.

So, I had following options...
1. Use SWFLoader component directly.
2. Use Loader or SWFLoader and get actual bytearray, load it as MovieClip.
3. Embed the swf and extract its symbol as class. This class will be further loaded as MovieClip.
4. Embed the animation with custom class created in flex.

So, lets talk about the last option...

First create animation with flash cs3. Make sure publish settings must be targeted to actionscript 3- FP9.
Create the animation in movieclip and export as symbol. Right click and make export for actionscript.
Now export and publish the swf.

Back to Flex 4...

Create a class something like this as per your need...

[Sample]
package com.prox
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.TimerEvent;
    import flash.utils.Timer;

    [Embed(source="res/swoosh.swf", symbol='Swoosh')]
    public class Swoosh extends MovieClip
    {
        private var tmr:Timer;
        public function Swoosh()
        {
            addEventListener(Event.ADDED_TO_STAGE, clbAddedToStage);
        }

        private function clbAddedToStage(event:Event):void
        {
            event.stopImmediatePropagation();
            removeEventListener(Event.ADDED_TO_STAGE, clbAddedToStage);

            gotoAndStop("park");
        }
...
...

Now, just use this class as normal custom classes you use...

var swoosh:Swoosh = new Swoosh();
addChild(swoosh);

That's it.

Do your comment

Error in iPhone while localization

Command /Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/Contents/Resources/copystrings failed with exit code 127

The error has taken hours of my time. Just copy and execute following command.
sh-3.2# cp /usr/bin/plutil /Developer/usr/bin/plutil

Thats it. huh!


Do your comment

Memory management, A habit!

Several times, programmers stuck in memory management issues. This is a basic issue which consumes many precious timeline hours.

In my view, memory management has a very separate track. I usually follow only one thing…

What you create, remove it yourself.

This is the main mantra for all programmers for any language. Never ever rely on self cleaning or GC. I am telling you what I experience.

Why not GC?

First thing, GC don’t know what you want to express with your code and so it works just as a routine. You better understand your baby and its need. Second thing, GC always take more time in cleaning than your logic. GC is a general routine and works similar for all. It can not behave special with your code.

So…use your own memory leak prevention system. The memory management techniques should be used since the beginning of the  project

Make a habit to remove everything what you have created. This will benefit you always in terms of precious timeline hours.

Lets look an example of negligence…

private function assignData(data:ArrayCollection):void
{
     this.objData = data;
}

Now what about the data:ArrayCollection which came here as a parameter? I have seen in 80% cases, people leave it as it is. This is also a reference to something and also occupy some memory. Remove it.

WHAT YOU CREATE, REMOVE IT.


Do your comment

Adding xml node in xml in flex: a simple way.

var xmlScreenShots:XML = new XML("<screenshots/>");
var nLen:int = 10;
var i:int;
var strData:String = "Value to be inserted.";
for(i = 0; i < nLen; i++)
{
      xmlScreenShots.appendChild(<mynode>{strData}</mynode>);
}

Do your comment

error initializing java runtime environment. you may need to reinstall flash

In Flash cs3 on mac, several times you may get this error…

“error initializing java runtime environment. you may need to reinstall flash”

To get rid of this, open a terminal and type this…

cd /System/Library/Frameworks/JavaVM.framework/Versions

Now, execute this sudo…

sudo ln -fhsv 1.5 CurrentJDK

Same as this you can change to other installed version.

Thats it.


Do your comment

AIR2 with NativeProcess and ImageMagick

Hi all again. AIR 2.0 is launched. A much awaited version that I was waiting for last 2 years. Lots of good things but what I like most is NativeProcess (run executables within as native process). I had done lots of tricks to execute commandline executables. But now its much easier. I bet…this feature alone, will give Adobe AIR a new height.

I have done some work with ImageMagick.

Here is the MagickUtils class.

package pravin.magick
{
 import flash.desktop.NativeProcess;
 import flash.desktop.NativeProcessStartupInfo;
 import flash.events.Event;
 import flash.events.ProgressEvent;
 import flash.events.IOErrorEvent;
 import flash.events.NativeProcessExitEvent;
 import flash.filesystem.File;
 /**
 * Image magick utility to use in Adobe AIR applications using NativeProcess.
 *  @author Pravin Ranjan
 *  @Date 16 June, 2010.
 */
 public class MagickUtils
 {
 private var objWorkingFolder:File;
 private var objOutFolder:File;
 private var process:NativeProcess;
 private var objConvertExe:File;
 /*Explicitely declared constructor.*/
 public function MagickUtils(objWorkingFolder:File,
 objOutFolder:File, onOutputData:Function,
 onErrorData:Function, onExit:Function, onIOError:Function)
 {
 this.objWorkingFolder = objWorkingFolder;
 this.objOutFolder = objOutFolder;

 objConvertExe = File.applicationDirectory.resolvePath("imagemagik/win/convert.exe");

 process = new NativeProcess();
 process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
 process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorData);
 process.addEventListener(NativeProcessExitEvent.EXIT, onExit);
 process.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
 process.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOError);
 }

 public function convertTo(strFromImage:String, strToImage:String):void
 {
 var objFile:File = objWorkingFolder.resolvePath(strFromImage);
 strFromImage = objFile.nativePath;
 strToImage = objOutFolder.nativePath + File.separator + strToImage;
 trace("strFromImage: " + strFromImage);
 trace("strToImage: " + strToImage);

 var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();
 nativeProcessStartupInfo.executable = objConvertExe;
 var processArgs:Vector.<String> = new Vector.<String>();
 processArgs.push(strFromImage);
 processArgs.push(strToImage);
 nativeProcessStartupInfo.arguments = processArgs;
 process.start(nativeProcessStartupInfo);
 }
 }
}

AND here is main class…

package
{
 import flash.display.Sprite;
 import flash.desktop.NativeProcess;
 import flash.desktop.NativeProcessStartupInfo;
 import flash.events.Event;
 import flash.events.ProgressEvent;
 import flash.events.IOErrorEvent;
 import flash.events.NativeProcessExitEvent;
 import flash.filesystem.File;
 import pravin.magick.MagickUtils;

 public class NativeProcessExample extends Sprite
 {
 public var process:NativeProcess;

 public function NativeProcessExample()
 {
 if(NativeProcess.isSupported)
 {
 setupAndLaunch();
 }
 else
 {
 trace("NativeProcess not supported.");
 }
 }

 public function setupAndLaunch():void
 {     
 var magik:MagickUtils = new MagickUtils(File.applicationDirectory, File.applicationDirectory, onOutputData, onErrorData, onExit, onIOError);
 magik.convertTo("MyImage.jpg", "OutImage.png");
 }

 public function onOutputData(event:ProgressEvent):void
 {
 trace("Got: ", process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable));
 }

 public function onErrorData(event:ProgressEvent):void
 {
 trace("ERROR -", process.standardError.readUTFBytes(process.standardError.bytesAvailable));
 }

 public function onExit(event:NativeProcessExitEvent):void
 {
 trace("Process exited with ", event.exitCode);
 }

 public function onIOError(event:IOErrorEvent):void
 {
 trace(event.toString());
 }
 }
}

ImageMagick path need to be changed and wow. It works perfectly. My app executes convert.exe and my desired output is generated.

Wait a minute…

Now what you need. AIR 2.0 SDK, AIR 2.0 runtime, ImageMagick and flash CS4 (latest one).

Your app xml would look like this…

<?xml version =”1.0″ encoding=”utf-8″ ?><application xmlns=”http://ns.adobe.com/air/application/2.0″><id>com.adobe.example.nativeprocess</id><supportedProfiles>extendedDesktop</supportedProfiles><version>1.0</version><filename>nativeprocess</filename><description></description><!– To localize the description, use the following format for the description element.<description><text xml:lang=”en”>English App description goes here</text><text xml:lang=”fr”>French App description goes here</text><text xml:lang=”ja”>Japanese App description goes here</text></description>–><name>nativeprocess</name><!– To localize the name, use the following format for the name element.<name><text xml:lang=”en”>English App name goes here</text><text xml:lang=”fr”>French App name goes here</text><text xml:lang=”ja”>Japanese App name goes here</text></name>–><copyright></copyright><initialWindow><content>nativeprocess.swf</content><systemChrome>standard</systemChrome><transparent>false</transparent><visible>true</visible></initialWindow><icon></icon><customUpdateUI>false</customUpdateUI><allowBrowserInvocation>false</allowBrowserInvocation></application>

Now compile. If all well, you’ll get a converted image. You can also create preformatted commands in actionscript to perform actions.

Thats it for now. See you soon.


Fisix engine vector class not working with flex.

While working with fisix engine with flex, I stucked in a situation…

1067: Implicit coercion of a value of type __AS3__.vec:Vector to an unrelated type com.fileitup.fisixengine.core:Vector.

I checked http://blog.maxkunz.de/?p=170 for the solution. Yeah, good solution but not worked on my problem.

There is another solution. Go to compiler option and add “-target-player=9.0.0″ as shown below.

Compiler option

Compiler option


Do your comment

Flex repeater control part 2

Return back again.

In this section we’ll see how to retrieve repeater item and its data.

Lets have our example…

<mx:VBox id="box" height="100%" width="100%">
     <mx:Spacer height="10"/>
     <mx:Repeater id="r" dataProvider="{xmlColMenu}" startingIndex="0" recycleChildren="true">
         <mx:LinkButton id="idx" label="{r.currentItem.name}" click="{clbClick(event);}" styleName="RightLink"/>
         <mx:Repeater id="s" dataProvider="{r.currentItem.link}" 
             startingIndex="0" recycleChildren="true">
            <mx:LinkButton id="idy" label="{s.currentItem.name}"
                click="{clbClick(event);}" fontFamily="Verdana"
                fontSize="9" fontStyle="normal" fontWeight="normal"
                textSelectedColor="#03598B" textRollOverColor="#47A318" disabledColor="#47A318" height="15"
                color="#666666" themeColor="#FFFFFF"/>
         </mx:Repeater>
     </mx:Repeater>
 </mx:VBox>

Now we will write clbClick event for the repeater item. Indeed, your event handler will be written in <mx:Script> block.

/**
 * Navigation item click event.
 * @param event of type MouseEvent.
 */
 private function clbClick(event:MouseEvent):void
 {
     trace(event.target.getRepeaterItem().id);
 }

If you use getRepeaterItem(), it gives you access to the data item that you’d set earlier while repeating the item.

<mx:LinkButton id="idx" label="{r.currentItem.name}" click="{clbClick(event);}" styleName="RightLink"/>

In my case, I need to access id. You may have different data.

In next section we’ll check how to update repeater control dynamically. Till then c. y.


Do your comment

Flex repeater control part1

Repeater control is very useful but little bit complex to understand.

Why flex introduced this repeater control. Very simple. To avoid unnecessary looping and to reduce complexity of component/s or control/s repeatation.

In simple way, we can do the same repeatation by using for loop or while or do-while loop. Repeater control saves our time.

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

  <mx:Script>
    <![CDATA[
      [Bindable]
      public var myArray:Array=[1,2,3,4];
    ]]>
  </mx:Script>

  <mx:ArrayCollection id="myAC" source="{myArray}"/>
  <mx:Repeater id="myrep" dataProvider="{myAC}">
    <mx:Label id="Label1" text="This is loop #{myrep.currentItem}"/>
  </mx:Repeater>
</mx:Application>

This is a simple example how the repeater component is used. Please note here that the repeater control is itself a loop so don’t need to use another loop to support the control.
We can also use nested repeater controls. Just like example below.

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

  <mx:Script>
    <![CDATA[
      [Bindable]
      public var myArray:Array=[1,2,3,4];
    ]]>
  </mx:Script>

  <mx:ArrayCollection id="myAC" source="{myArray}"/>
  <mx:Repeater id="myrep" dataProvider="{myAC}">
    <mx:Label id="Label1" text="This is loop #{myrep.currentItem}"/>
    <mx:Repeater id="nestedrep" dataProvider="{myrep.currentItem.secondaryXMLList}">
        <mx:Label id="Label2" text="This is loop #{nestedrep.currentItem}"/>
     </mx:Repeater>  
   </mx:Repeater>
</mx:Application>

In next series, we’ll see how to retrieve data from repeated controls or components. We’ll also see controlling and refreshing the repeater component.

ciao.


Do your comment

The site name is now very simple

The site name is changed from pravinranjan.com to pranjan.com.

Its simple to say now pranjan [p r a n j a n].
:)


Do your comment