Tuesday, 23. December 2008
finally got rid of the problem of debugging my flex application
finally sorted out the problem i was having while debugging my flash application. It was working well till yesterday but suddenly i could not debug my flex applicationt this morning. I searched on the internet for it and voila!!!, i have to say i found the silver bullet to my problem.

I ran my flex application and while the flex builder is trying to connect to the debugger, i quickly right clicked on my application and clicked on 'Debugger', then on the dialog box that appears i chose 'Other Machine' and gave 127.0.0.1 as the ip addres.

Still i don't know the root cause of the problem but the good news for me is, it saved my time and of course my precious 'man hours' ;).

Thanks to
http://therush.wordpress.com/2008/03/11/resolved-flex-builder-3-debugger-stopped-working/?referer=sphere_related_content/

... link (0 Kommentare)   ... comment


Friday, 8. August 2008
displaying popup around mouse on some event clicked in the container without being clipped off by the screen

There might be the cases when you want to show a popup around your mouse on events such as mouseDown, dropDrop, mouseClick. The problem one can face while doing that is the popup can get clipped off at the edge of the screen if you simply position the popup based on the coordinates of the mouse without any extra measures. Have a look at the following code:

PopUp.mxml

<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="vertical"
    width="300" height="50"
    styleName="customPopUp"
    showCloseButton="true"
    close="handleClose(event)"
    headerHeight="4"
    >

    <mx:Text width="100%" height="100%" text="This is a test popup"/>

    <mx:Script>
        <![CDATA[
            import mx.managers.PopUpManager;
            import mx.events.CloseEvent;

            private function handleClose(evt:CloseEvent):void {
                PopUpManager.removePopUp(this);

            }
        ]]>
    </mx:Script>
</mx:TitleWindow>
main.mxml
<mx:Application
    xmlns:mx="http://www.adobe.com/2006/mxml"
    layout="absolute" click="showDetail(event)">
    <mx:Script>
        <![CDATA[
            import mx.managers.PopUpManager;

            private const POPUP_OFFSET:int = 10;

            private function showDetail(evt:MouseEvent):void {
            	
                var popup:PopUp = PopUp(PopUpManager.createPopUp(this, PopUp,false));
				
		var tempX:Number = evt.currentTarget.mouseX + POPUP_OFFSET;
		var tempY:Number = evt.currentTarget.mouseY;
				
				
                popup.x = tempX;
                popup.y = tempY;
            }
        ]]>
    </mx:Script>
</mx:Application>

Demo showing the problem:





What you can notice here is whenever you click at the edge of the screen especially on the right side, the title window gets clipped off. Its because i simply get the mouse coordinates and place the popup at that coordinates with some offset in the x direction. To adjust the coordinates of the popup such that it will appear in the screen no matter where you click the mouse, you have to keep into consideration the application screen width and height. How? Have a look at the code snipped below:

var applicationWidth:Number = application.width;
var applicationHeight:Number = application.height;
				
var popupWidth:Number = popup.width;
var popupHeight:Number = popup.height;
				
if((tempX + popupWidth) > applicationWidth){
     tempX = tempX - POPUP_OFFSET - popupWidth;
}
				
if((tempY + popupHeight) > applicationHeight){
	tempY = tempY - popupHeight;
}
Here i have added coordinates of mouse on which click occurs with the width and height of the popup and see they are greater than the width and height of the application screen which i can get from the expressions application.width and application.height. If any or both of them are greater, then i adjust the position of the popup such that it will all be in the screen. Suppose x coordinate of mouse on which click occur together with the width of the popup as well as offset value is greater than width of the application screen, then it means your popup will gonna clipped off on the right side of the screen. So what i did was i moved the x positon of the screen left by the width of the popup plus the offset from the x coordinate of the mouse where click occured.

Well, you can adjust the code to localize the popup within any container of your screen taking into account the width and height of the container along with the widht and height of the popup as well as the coordinates.

Demo :





... link (0 Kommentare)   ... comment


Wednesday, 6. August 2008
using timer to make listeners for mouseMove and click for the same component work without any conflict

Recently i had a problem of making mouseDown and click work on the same component as i was having difficulty to separate those two events. The problem was whenever i click it triggers the mouseDown first which i didn't want to happen. I was searching for a way to somehow distinguish between mouse down and click. As a click consists of mouse down and mouse up with very short time interval in general, i thought of deferring the action to be taken for mouseDown for an interval of time and see if mouseUp happens or not during that interval. If during that interval mouseUp occurs, then it was regarded as a click and click operation can be carried out. If not, then mouseDown's deferred action will come into act. So i used a timer to defer the action carried out in mouseDown for certain time say 300 ms. The code snippet is shown below:

private var interval:Number = 0;

private function mouseDownHandler(event:MouseEvent) : void {
	//one can store the event variable for later use in the deferred handler
	
	clearInterval(interval);
	interval = setInterval(deferredMouseDownHandler, 300);
}

private function deferredMouseDownHandler() : void {
	clearInterval(interval);
	//carry out the required actions
}

private function clickHandler(event:MouseEvent) : void {
	clearInterval(interval);
	//carry out the required action
}

setInterval is used to execute specified function at time interval specified. So one must be careful to use clearInterval in the deferred handler as well as the click handler so that the function is not re-executed. Here all the actions required to be performed in mouseDownHandler are moved to deferredMouseDownHandler. Now whenever mouseDown occurs then the system will wait for 300 ms as specified in here before deferredMouseDownHandler is executed and during that interval if click occurs then clickHandler will use clearInterval to stop the execution of deferredMouseDownHandler. If click does not occur withing 300 ms, then deferredMouseDownHandler will come into act.

What is achieved so far is whenever click occurs such that interval between mouse down and mouseup is less than 300 ms, mouseDownHandler will not be triggered first. However, When the mouse is down for more than 300 ms, then deferredMouseDownHandler will be executed and if whenever mouse is up, clickHandler will still come into act. So if you don't want to trigger the click after deferredMouseDownHandler is executed, few more efforts will be required. The whole working code is given below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" layout="vertical" verticalGap="5" horizontalAlign="center" verticalAlign="middle">
	<mx:Script>
		<![CDATA[
			private var interval:Number = 0;
			private var isMouseDown:Boolean = false;
			
			private function mouseDownHandler(event:MouseEvent) : void {
				clearInterval(interval);
				interval = setInterval(deferredMouseDownHandler, 300);
			}
			
			private function deferredMouseDownHandler() : void {
				clearInterval(interval);
				isMouseDown = true;
				actionStatus.text += "\nmouse down";
			}
			
			private function clickHandler(event:MouseEvent) : void {
				if(!isMouseDown){
					clearInterval(interval);
					actionStatus.text += "\nmouse click";
				}
				isMouseDown = false;
			}
		]]>
	</mx:Script>
	<mx:Label text="Click or Mouse Down on me" color="#000405" fontSize="12" mouseDown="mouseDownHandler(event)" click="clickHandler(event)" />
	<mx:Text width="147" id = "actionStatus"/>
</mx:Application>

I have used a flag isMouseDown which i set to true whenever the deferredMouseDownHandler is executed. Now when clickHandler is executed,it first checks this flag before carrying out its actions. This will help in completely isolating click actions from mouseDown actions.

This technique assumes that during click, the time interval between mouse up and mouse down is less than 300 ms. The interval can be adjusted as per the requirement.



Demo:





... link (0 Kommentare)   ... comment


Thursday, 31. July 2008
background color required when using container as a drop target

Lately i was working on a drag and drop for my project and i have to allow the user to drag and item from one container to another container. Somehow the drag and drop was not working though the code looks fine.The drag manager was not allowing to drop the item on the target container. This was freaking me out as the drag and drop handling code seems ok. After searching on the internet i found that to use container as a drop target, the background color of the container should not be transparrent as doing so the drag and drop manager will not be able to detect whether the mouse pointer is on a possible drop target.The backgroundColor property should be set for this to work.

The code shown below uses simple drag and drop of an image within a container:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" layout="horizontal"  borderColor="#3D7FAD" horizontalAlign="center" verticalAlign="middle">
<mx:Script>
	<![CDATA[
		import mx.containers.Canvas;
		import mx.events.DragEvent;
		import mx.controls.Image;
		import mx.core.IUIComponent;
		import mx.managers.DragManager;
		import mx.core.DragSource;

		
		private function mouseMoveHandler( evt:MouseEvent ):void {
	       	var dragInitiator:Image=Image(evt.currentTarget);
	       	var ds:DragSource = new DragSource();
	       	ds.addData(dragInitiator, "test");               
	       	DragManager.doDrag(dragInitiator, ds, evt);
        }
        
        private function dragEnterHandler( evt:DragEvent ):void {
        	if (evt.dragSource.hasFormat("test")) {
                    DragManager.acceptDragDrop(Canvas(evt.currentTarget));
            }
        }
        
        private function dropHandler( evt:DragEvent ):void {
        	evt.dragSource.dataForFormat("test").x = evt.currentTarget.mouseX;
            evt.dragSource.dataForFormat("test").y = evt.currentTarget.mouseY;
        }

        
	]]>
</mx:Script>
	<mx:Canvas  width="90%" height="90%" dragEnter="dragEnterHandler(event);" dragDrop="dropHandler(event);" borderColor="#2D5A7A" borderStyle="solid">
		<mx:Image id="img" width="40" height="40" source="@Embed('../assets/task.png')" mouseMove="{mouseMoveHandler(event)}" />
	</mx:Canvas>
</mx:Application>

the demo is shown below:






As you can see the drag and drop is not working due to the background of the container being transparrent. Now if we set the backgroundColor property of the container as backgroundColor="#EEEEEE", the drag and drop will work which is shown below.






Sometimes, these minor problems can take considerable time to get to the solution. I will be careful from now on ... :).

... link (0 Kommentare)   ... comment


Wednesday, 16. July 2008
Creating an In – Place Editor in Flex

In Flex you can use item editor to edit the data in a list based control. You can use default item editing mechanism or you can create your own item editor. However, if you want to add an inline editing mechanism in other components like Text and Label, you have to find a workaround yourself. In this post I will try to explain the way I often use to create in – place editor in my application using view stack.

Using view stack you can create stack of two components viz. the text component and text area/text input component. The click listener is added to the text component and on clicking the text component the selecteIndex or selectedChild property of view stack is changed to show the text editing component.

The simplest of code to accomplish this is shown below:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" width="100%" height="100%" xmlns:local="*">
	<mx:Script>
		<![CDATA[
			[Bindable]
			public var testText:String = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.";
		]]>
	</mx:Script>
	<mx:ViewStack id="editStack" width="100%"  selectedIndex="0" height="100%">
		<mx:Box width="100%" height="100%">
			<mx:Text id="readOnlyTitle" width="100%" fontSize="12" click="{editStack.selectedIndex = 1;if(editArea != null){editArea.setFocus();}}" text="{testText}" />
		</mx:Box>
		<mx:HBox width="100%" verticalAlign="bottom" height="50">
			<mx:TextArea id="editArea" fontSize="12" width="100%" text="{testText}" creationComplete="{editArea.setFocus()}" height="50"/>
			<mx:Button label="Ok" click="testText=editArea.text;editStack.selectedIndex = 0" />
			<mx:Button label="Cancel" click="editArea.text=testText;editStack.selectedIndex = 0" />
		</mx:HBox>
	</mx:ViewStack>
</mx:Application>

Inside Script, I have defined a variable which I will bind to the text property of text and textarea components.

I have created a viewstack which has two containers – one for text component and another for textarea component. The selectedIndex property of viewstack is set to 0 initially which will show only the text component.

On clicking the text component, the selectedIndex property of view stack is changed to 1 which will show textarea component in place of text component and the focus is set to textarea component.

Along with textarea component, two buttons are also shown for user to save or cancel the editing at any time and go back to previous state in which text component is only visible. Adding buttons is not mandatory, user can even use keyboard listener to save or cancel the editing based on the press of ENTER and ESC keys respectively.

The demo is shown below:






Click on the text to edit it.

... link (0 Kommentare)   ... comment


Sunday, 13. July 2008
Fading effect does not work on text rendered without using embedded font

Recently I had a problem in making fade effect work on text component. After few search in the internet found a solution to this problem, in fact a workaround.

Actually, if we apply Fade and Rotate effects to text component or any controls using text using system font, nothing happens with the text. Instead of fading effect, one will come across with single instant where the text appears and disappears depending upon the nature of fade effect. You can verify this using this simple code:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute">
	
	<mx:Fade id="fadeOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
	<mx:Fade id="fadeIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
	<mx:Label id="testLbl" x="114" y="96" text="testing fading effect" showEffect="{fadeIn}" hideEffect="{fadeOut}"/>
	<mx:Button x="104" y="137" label="Fade In" click="{testLbl.visible=true}"/>
	<mx:Button x="177" y="137" label="Fade Out" click="{testLbl.visible=false}"/>
</mx:Application>

For the fading effect to work with text component, we have to embed the font as shown below:

…………………….
<mx:Style>
		@font-face{
			src: url("../assets/ARIAL.TTF");
			fontFamily:"myFont";
		}
</mx:Style>
..........
	<mx:Label id="testLbl" x="114" y="96" fontFamily="myFont" text="testing fading effect" showEffect="{fadeIn}" hideEffect="{fadeOut}"/>
	
..........

Just embed a font as shown above and add a property to the label component “fontFamily” specifying the embedded font. This time you can see that the fading effect works.

Another work around is to apply Blur filter to the text before applying any effects to it. This way you don’t require to embed the font.
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" >
	<mx:Script>
		<![CDATA[
			private function applyBlurFilter():void {
			  var blurfilter:BlurFilter = new BlurFilter(0,0,0);
			  var filters:Array = new Array();
			  filters.push(blurfilter);
			  testLbl.filters = filters;
			}
		]]>
	</mx:Script>
	<mx:Fade id="fadeOut" duration="1000" alphaFrom="1.0" alphaTo="0.0"/>
	<mx:Fade id="fadeIn" duration="1000" alphaFrom="0.0" alphaTo="1.0"/>
	<mx:Label id="testLbl" x="114" y="96" text="testing fading effect" showEffect="{fadeIn}" hideEffect="{fadeOut}" creationComplete="{this.applyBlurFilter()}"/>
	<mx:Button x="104" y="137" label="Fade In" click="{testLbl.visible=true}"/>
	<mx:Button x="177" y="137" label="Fade Out" click="{testLbl.visible=false}"/>
</mx:Application> 

... link (0 Kommentare)   ... comment


Saturday, 28. June 2008
Workaround for the unavailability of the constructor and method overloading in Actionscript 3

It’s been few months I have been working on ActionScript and I was pretty disappointed by the fact that ActionScript does not support function overloading. I wonder why that is. Function overloading is what I have been using very often while working in Java and C#.

However, unavailability of constructor and method overloading does not handicap Actionscript 3. It is still powerful programming language enhanced architecturally and conceptually compared to previous version.
There are two workarounds I have known so far for the unavailability of function overloading in ActionScript3.
  • Using default parameters which will allow to call function with different number of parameters
  • Using …..(rest) parameter i.e. ellipses followed by the name

The first one is pretty easy. The function should contain all the required parameters with default value associated with the parameters. For example:

public function foo(param1:int = 0, param2:int = 0, param3:int = 0):void{
//do something
}
foo(2); //only param1 is provided. param2 and param3 will take the default value
foo(4,5); //param3 will take the default value

The second solution is to use rest parameter. The rest parameter is denoted by using ellipses followed by the name of the parameter as shown below:

public function foo(…..params):void{
//do something
}

Using rest parameter allows a function to accept any number of comma delimited arguments which will be available to function in the form of array. For example:

foo( 2,3,4,5);
All these arguments will be available to function as array such that first argument can be accessed using params[0] and so on.

The main issue with rest parameter is type safety. Using reset parameter means you will lose compile-time type safety.

Though there are few workarounds, I still prefer native method overload support which I hope will be introduced in future version.

... link (1 Kommentar)   ... comment