Solved

How to attach event listeners to custom components created in run time.

Posted on 2008-06-25
11
718 Views
Last Modified: 2008-06-27
Hello All,

I have a custom component called layoutPhotoItem and it  has a event called meSelected, which is dispatched when someone clicks on the component.
A function in the main application called listenMeSelected is supposed to handle the logic when the component is clicked.
If I drag a layoutPhotoItem from the user interface of flex builder and handle the event there everything works fine.

But when I try to do it by code, like in the sample I pasted below, I get a
1119: Access of possibly undefined property meSelected through a reference with static type layoutPhotoItem.
error and the IDE wont comply.

I'm quite new to flex but not to coding, I'm guessing I'm missing something fundamental.
Can anybody help me on this ?

Thanks in advance

Cheers

C
this works fine... the event is dispatched, listened by te handler etc.
<ns1:layoutPhotoItem x="440" y="200" meSelected="listenMeSelected(event)">
 
this one fails..
 
private function addPhotoitem():void{
	var pi:layoutPhotoItem = new layoutPhotoItem
	addEventListener(pi.meSelected,listenMeSelected) // this line fails...
	this.addChild(pi)
}

Open in new window

0
Comment
Question by:wildcard76
  • 6
  • 5
11 Comments
 
LVL 13

Expert Comment

by:bglodde
ID: 21867635
Try adding the event listener to the layoutPhotoItem. Declaring it as you have done adds the event listener to the application instead of the child object.
pi.addEventListener(pi.meSelected, listenMeSelected);
0
 
LVL 13

Expert Comment

by:bglodde
ID: 21867645
Also, can you post layoutPhotoItem? The exception indicates a property that is not accessible/undefined through that object.
0
 
LVL 3

Author Comment

by:wildcard76
ID: 21867883
sure here's the code to the component
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="144" height="94" creationComplete="doInit()">
 
<mx:Metadata>
 	[Event(name="meSelected", type="flash.events.Event")]
 </mx:Metadata>
<mx:Script>
	<![CDATA[			
		//local flags
		
		private var currentAction:String
		private var xOff:int
		private var yOff:int
		private var riconHandle:DisplayObject
		private var rh:rotateHandle
		
		//property gibi degil gibi
		public var isSelected:Boolean = false
		public var borderSize:int = 3
		public var imageURL:String=''
		
	
		
		private function doMD(event:MouseEvent):void{
			currentAction='moving'			
			xOff = event.currentTarget.mouseX
			yOff = event.currentTarget.mouseY	
			beSelected()
		}	
		
		private function doMU(event:MouseEvent):void{
			currentAction=''				
		}	
		
		private function doMM(event:MouseEvent):void{
			if(currentAction=='moving'){	
				riconHandle.x = riconHandle.x + (parent.mouseX - xOff - this.x)
            	riconHandle.y = riconHandle.y + (parent.mouseY - yOff - this.y)				
				x = parent.mouseX - xOff  
            	y = parent.mouseY - yOff
			}
			
			if (currentAction=='resizingBottomRight'){
				this.width -= 1
				this.height -= 1
				resetBorders()
			}			
		}
		
		private function doMO(event:MouseEvent):void{
			currentAction=''			
		}
		
		
		
		private function beSelected():void{
			if(isSelected != true){
				isSelected=true
				rh = new rotateHandle
				riconHandle = parent.addChild(rh)
				rh.x = this.x + this.width /2
				rh.y = this.y - rh.height*2
				rh.rotateObject=this	
				var  theEvent:Event= new Event("meSelected") 
				this.dispatchEvent(theEvent)	
				showModifierControls()			
			}				
		}
		
		public function beUnselected():void{
			parent.removeChild(riconHandle)
			isSelected=false	
			currentAction=''	
			hideModifierControls()		
		}
		
		
		
 
		private function doInit():void{			
			if (imageURL != ''){
					picholder.source=imageURL;
					picholder.visible=true;
				} 
			
			else{
					picholder.visible=false
				}				
			var filters:Array = new Array();
		    var dFilter:DropShadowFilter = new DropShadowFilter();
      		filters.push(dFilter);
      		this.filters = filters;		
      		resetBorders()
      		hideModifierControls()      		      					 
		}
			
			private function resetBorders():void{
				//arrange the border lines
				bLeft.x = 3
				bLeft.y = 3
				bTop.x = 3
				bTop.y = 3			
				bRight.x= this.width-bRight.width - 3 
				bRight.y=3	
				bBottom.x=3
				bBottom.y= this.height - bBottom.height - 3
				
				//arrange the resizing handles
				rszHandle_topLeft.x=0
				rszHandle_topLeft.y=0
				rszHandle_topRight.x= this.width - rszHandle_topRight.width
				rszHandle_bottomLeft.x=0
				rszHandle_bottomLeft.y=this.height-rszHandle_bottomLeft.height
				rszHandle_bottomRight.x= this.width- rszHandle_bottomRight.width	
				rszHandle_bottomRight.y= this.height- rszHandle_bottomRight.height
				
				//arrange the backplane and frontplane
				backPlane.width=this.width -6
				backPlane.height=this.height -6
				backPlane.x=3
				backPlane.y=3
				frontPlane.width=this.width -6
				frontPlane.height=this.height -6
				frontPlane.x=3
				frontPlane.y=3
				
				//arrange the picture holder
		
				picholder.width = this.width - borderSize*2-5
				picholder.height = this.height - borderSize*2-5				
							
				picholder.x= 0			
				picholder.y= 0
				
				picCanvas.width=this.width - borderSize*2
				picCanvas.height=this.height - borderSize*2			
				picCanvas.x = borderSize
				picCanvas.y = borderSize
				
				
				
				
				picholder.x=3
				picholder.y=3	
				
				
				
				
															
			}
			
			public function showModifierControls():void{
				bLeft.visible=true
				bRight.visible=true
				bTop.visible=true
				bBottom.visible=true
				rszHandle_topLeft.visible=true
				rszHandle_topRight.visible=true
				rszHandle_bottomLeft.visible=true
				rszHandle_bottomRight.visible=true
			}
			
			public function hideModifierControls():void{
				bLeft.visible=false
				bRight.visible=false
				bTop.visible=false
				bBottom.visible=false
				rszHandle_topLeft.visible=false
				rszHandle_topRight.visible=false
				rszHandle_bottomLeft.visible=false
				rszHandle_bottomRight.visible=false
			}
				
				
			private function doResizeBottomRightMD(event:MouseEvent):void{
				currentAction='resizingBottomRight'
				lbl.text='resizingBottomRight'					
			}
			private function doResizeBottomRightMU(event:MouseEvent):void{
				currentAction='resizingBottomRight'
				lbl.text=''					
			}
			
			private function doResizeBottomLeftMD(event:MouseEvent):void{
				currentAction='resizingBottomLeft'	
				lbl.text='resizingBottomLeft'				
			}
			private function doResizeBottomLeftMU(event:MouseEvent):void{
				currentAction='resizingBottomLeft'
				lbl.text=''					
			}
			
			private function doResizeTopLeftMD(event:MouseEvent):void{
				currentAction='resizingTopLeft'
				lbl.text='resizingTopLeft'					
			}
			private function doResizeTopLeftMU(event:MouseEvent):void{
				currentAction='resizingTopLeft'
				lbl.text=''					
			}
			
			private function doResizeTopRightMD(event:MouseEvent):void{
				currentAction='resizingTopRight'	
				lbl.text='resizingTopRight'				
			}
			private function doResizeTopRightMU(event:MouseEvent):void{
				currentAction='resizingTopRight'
				lbl.text=''					
			}
			
	]]>
	
</mx:Script>	
	
	
	<mx:Box id="backPlane" backgroundColor="#FFFFFF"></mx:Box>
	
	<mx:Canvas id="picCanvas" mouseDown="doMD(event)" mouseUp="doMU(event)" mouseMove="doMM(event)" x="0" y="0" width="56" height="56">
		<mx:Image width="50" height="50" id="picholder" scaleContent="false" autoLoad="true" rotation="0" x="0" y="0"/>	
	</mx:Canvas>
	<mx:Box id="frontPlane" backgroundAlpha="40"></mx:Box>
		
	<mx:Box id="bLeft" width="5" height="100%" backgroundColor="#FF0000"/>
	<mx:Box id="bRight" width="5" height="100%" backgroundColor="#FF0000"/>
	<mx:Box id="bTop" width="100%" height="5"  backgroundColor="#FF0000"/>
	<mx:Box id="bBottom" width="100%" height="5" backgroundColor="#FF0000"/>
				
	<mx:Box id="rszHandle_topLeft" width="10" height="10" backgroundColor="#FFFF00" mouseDown="doResizeTopLeftMD(event)" mouseUp="doResizeTopLeftMU(event)" />
	<mx:Box id="rszHandle_topRight" width="10" height="10" backgroundColor="#FFFF00" mouseDown="doResizeTopRightMD(event)" mouseUp="doResizeTopRightMU(event)" />
	<mx:Box id="rszHandle_bottomLeft" width="10" height="10" backgroundColor="#FFFF00" mouseDown="doResizeBottomLeftMD(event)" mouseUp="doResizeBottomLeftMU(event)" />
	<mx:Box id="rszHandle_bottomRight" width="10" height="10" backgroundColor="#FFFF00" mouseDown="doResizeBottomRightMD(event)" mouseUp="doResizeBottomRightMU(event)" /> 	
	<mx:Label x="10" y="144" text="Label" width="232" id="lbl"/>
	
		
	
	
</mx:Canvas>

Open in new window

0
Does Powershell have you tied up in knots?

Managing Active Directory does not always have to be complicated.  If you are spending more time trying instead of doing, then it's time to look at something else. For nearly 20 years, AD admins around the world have used one tool for day-to-day AD management: Hyena. Discover why

 
LVL 3

Author Comment

by:wildcard76
ID: 21867949
I did not exactly get what you mean by adding the event listener to the child object instead of the main application, because that's what i intend to achieve...

Basicaly, during run time, the user might create an arbitrary number of layoutPhotoItem components. I want to unselect any other layoutPhotoItem components when one is selected. So I thought the main application should listen to the meSelected events, when hears one, iterates through all layoutPhotoItems in the childcontrols, run a "beUnselected" on the instances other than the one that fires the event.

Of course it doesnt necessarily be in the application, the listener can also be on the child object, given that the fired event propagates to the sibling controls in the same container right ?  A little like loose-coupling fashion.

Cheers

C
0
 
LVL 3

Author Comment

by:wildcard76
ID: 21867976
I tried your suggestion
pi.addEventListener(pi.meSelected,listenMeSelected)
still the same.
0
 
LVL 13

Accepted Solution

by:
bglodde earned 500 total points
ID: 21868061
When I create custom components, I almost always create custom events as well. When I do that, the name of the event is always referred to by name (String).

Let's see if this works:
addEventListener("meSelected", listenMeSelected)


0
 
LVL 13

Expert Comment

by:bglodde
ID: 21868180
Sorry I meant the name of the event is what the event listener goes by...
0
 
LVL 3

Author Comment

by:wildcard76
ID: 21872134
Hello Again,

I tried the string version, addEventListener("meSelected", listenMeSelected)
this time the compiler does not protest and run but the event does not trigger.

The instance I drop on the canvas using the IDE works fine, the one created by code does not :(

Cheers

c
0
 
LVL 3

Author Comment

by:wildcard76
ID: 21881419
I figured it out.... simple..
bubbles=true

fixed it for me.. .

way more ground to cover for me I'm afraid ;)

thanks for helping

cheers
c
0
 
LVL 13

Expert Comment

by:bglodde
ID: 21883684
Ah! Sad that I missed it!
0
 
LVL 3

Author Comment

by:wildcard76
ID: 21885102
Flex has a peculiar way of handling events,
I got rather confused in the beginning, for instance when I realized a listener at the application level listens to the mousedown events of some arcane control in a unsuspected component and tries to fire events...

for now as general practise, I try to call event.stoppropagation as soon as I finish handling the event... otherwise who knows who else might hadle the event up in the container hierarchy :)

cheers

c
0

Featured Post

Optimizing Cloud Backup for Low Bandwidth

With cloud storage prices going down a growing number of SMBs start to use it for backup storage. Unfortunately, business data volume rarely fits the average Internet speed. This article provides an overview of main Internet speed challenges and reveals backup best practices.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
AS 3 Eval 5 489
Keep a player within a circular area 3 259
Flash player stream to ipad: is that possible ? 4 531
Facebook Flash API - How do you edit MobileLoginWindow.as? 4 753
First things first - Preparation We need all the part for this install and it's much nicer to have them all on hand when you need them so here's what's required. Download Eclipse 3.5 32 bit (I like the Classic flavour) from here. (http://www.e…
Do you use a spreadsheet like Microsoft's Excel?  Have you ever wanted to link out to a non excel file on your computer or network drive?  This is the way I found to do it!
Finds all prime numbers in a range requested and places them in a public primes() array. I've demostrated a template size of 30 (2 * 3 * 5) but larger templates can be built such 210  (2 * 3 * 5 * 7) or 2310  (2 * 3 * 5 * 7 * 11). The larger templa…

777 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question