I'm building a panel of buttons, that are enclosed in Canvas container. For this purpose I created a MyButton
class, which is a subclass of UIComponent. MyButton class has 2 other subclasses: MyRadioButton
and MyMenuButton
, which have another behavior on MouseEvent.MOUSE_DOWN
. MyMenuButton
creates and shows a menu, that I build from XML and it builds ok.
I add listeners in the superclass like this:
this.addEventListener(MouseEvent.CLICK, handleClick);
this.addEventListener(MouseEvent.MOUSE_DOWN, handleMouse);
this.addEventListener(MouseEvent.MOUSE_UP, handleMouse);
It's done at the creation stage.
In my subclasses I override handleMouse
handler.
override protected handleMouse(event:MouseEvent) : void
{
// subclass specific handling
}
These button objects are added to canvas container as following:
in class MyButtonsContainer.as
:
this.rowChildren.addChild(button);
These buttons draw perfectly and in place. The problem is the behavior: The event doesn't come to handleClick handler of superclass. And that's the question actually - why can it be? Thanks in advance
EDIT: It appears that MOUSE_DOWN & MOUSE_UP interfere with CLICK event. When I remove listeners to them I get to click handler.How to cause them live together?
I managed to catch CLICK
event as timing difference between MOUSE_DOWN
& MOUSE_UP
.
EDIT: A short/long explanation: For some reason my listeners for MOUSE_DOWN/MOUSE_UP
events were interfering with MouseEvent.CLICK
. I was suggested by somebody to give up on listening to MouseEvent.CLICK
and instead start a timer in MouseEvent.MOUSE_DOWN
and check again the timer in MouseEvent.MOUSE_UP
. If the difference less than 0.1 (you can put there another threshold) then it was a click actually.
Now some sample code:
public class MyButton extends UIComponent
{
...
private var _clickTime : Number = 0.;
public function void MyButton()
{
super();
addEventListener(MouseEvent.MOUSE_DOWN, handleMouse);
addEventListener(MouseEvent.MOUSE_UP, handleMouse);
}
protected function checkForClick(event:MouseEvent) : Boolean
{
var down : Boolean = event.type == MouseEvent.MOUSE_DOWN;
if (down)
_clickTime = getTimer();
else {
var diff : Number = getTimer() - _clickTime;
if (diff/1000. < 1.) {
handleClick();
return true;
}
}
return false;
}
protected function handleClick(event:MouseEvent) : void
{
// handle the click here
}
protected function handleMouse(event:MouseEvent) : void
{
checkForClick(event);
...
// take care of your button graphic state
}
DISCLAIMER: This code works for me and good for me and my application needs. If you disagree with this way or have a better way to suggest, please do it in comments. Since this answer answers my own question and this EDIT was added only because I was asked to do so, please don't downvote it if you don't agree with it.