Solved

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

Posted on 2008-06-25
11
722 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Put Machine Learning to Work--Protect Your Clients

Machine learning means Smarter Cybersecurity™ Solutions.
As technology continues to advance, managing and analyzing massive data sets just can’t be accomplished by humans alone. It requires huge amounts of memory and storage, as well as high-speed processing of the cloud.

 
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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

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…
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
There are cases when e.g. an IT administrator wants to have full access and view into selected mailboxes on Exchange server, directly from his own email account in Outlook or Outlook Web Access. This proves useful when for example administrator want…
Add bar graphs to Access queries using Unicode block characters. Graphs appear on every record in the color you want. Give life to numbers. Hopes this gives you ideas on visualizing your data in new ways ~ Create a calculated field in a query: …

632 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