Solved

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

Posted on 2008-06-25
11
720 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
Resolve Critical IT Incidents Fast

If your data, services or processes become compromised, your organization can suffer damage in just minutes and how fast you communicate during a major IT incident is everything. Learn how to immediately identify incidents & best practices to resolve them quickly and effectively.

 
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

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Advanced Datagrid with checkbox 4 311
why .swf is not adjusting to window.open() for 75%zoom in windows7 18 465
How popular is Java FX these days? 5 366
Flex 3 trace output 13 739
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…
This article demonstrates probably the easiest way to configure domain-wide tier isolation within Active Directory. If you do not know tier isolation read https://technet.microsoft.com/en-us/windows-server-docs/security/securing-privileged-access/s…
Attackers love to prey on accounts that have privileges. Reducing privileged accounts and protecting privileged accounts therefore is paramount. Users, groups, and service accounts need to be protected to help protect the entire Active Directory …

685 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