Handle MouseEvent.CLICK, MOUSE_DOWN in subclasses

Nava Carmon picture Nava Carmon · May 17, 2011 · Viewed 9.2k times · Source

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. MyMenuButtoncreates 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?

Answer

Nava Carmon picture Nava Carmon · May 23, 2011

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.