Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 724
  • Last Modified:

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

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
wildcard76
Asked:
wildcard76
  • 6
  • 5
1 Solution
 
bgloddeCommented:
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
 
bgloddeCommented:
Also, can you post layoutPhotoItem? The exception indicates a property that is not accessible/undefined through that object.
0
 
wildcard76Author Commented:
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
 The Evil-ution of Network Security Threats

What are the hacks that forever changed the security industry? To answer that question, we created an exciting new eBook that takes you on a trip through hacking history. It explores the top hacks from the 80s to 2010s, why they mattered, and how the security industry responded.

 
wildcard76Author Commented:
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
 
wildcard76Author Commented:
I tried your suggestion
pi.addEventListener(pi.meSelected,listenMeSelected)
still the same.
0
 
bgloddeCommented:
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
 
bgloddeCommented:
Sorry I meant the name of the event is what the event listener goes by...
0
 
wildcard76Author Commented:
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
 
wildcard76Author Commented:
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
 
bgloddeCommented:
Ah! Sad that I missed it!
0
 
wildcard76Author Commented:
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

[Webinar] Cloud and Mobile-First Strategy

Maybe you’ve fully adopted the cloud since the beginning. Or maybe you started with on-prem resources but are pursuing a “cloud and mobile first” strategy. Getting to that end state has its challenges. Discover how to build out a 100% cloud and mobile IT strategy in this webinar.

  • 6
  • 5
Tackle projects and never again get stuck behind a technical roadblock.
Join Now