AS3 KeyboardEvents not firing until after I’ve clicked on an onscreen button

actionscript-3flash

So here's my setup:

My document class is Main.as (it extends MovieClip). The following code is in my Main.as.

I've declared all these variables in my class definition:

private var holder:MovieClip;
private var leftButton:SimpleButton;
private var rightButton:SimpleButton;

in constructor…

holder = new MovieClip();
addChild(holder);
holder.addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);

leftButton = new Arrow();
rightButton = new Arrow();

holder.addChild(leftButton);
holder.addChild(rightButton);

leftButton.x = 50;
leftButton.rotation = 180;
rightButton.x = 150;

leftButton.y = rightButton.y = 50;

leftButton.addEventListener(MouseEvent.CLICK, handlePaging);
rightButton.addEventListener(MouseEvent.CLICK, handlePaging);

…outside of constructor…

public function handleKeyboardEvent ( e:KeyboardEvent ) {
            trace("got a keyboard event");

                trace("e.charCode : " + e.charCode);
                trace("e.keyCode : " + e.keyCode);
                switch (e.keyCode) {
                    case 37: //left arrow
                        showPreviousMoment();
                        break;
                    case 39: //right arrow
                        showNextMoment();
                        break;
                }


        }

The two buttons are instances of an Arrow movieclip that I have in the library. The Arrow movie clip just has graphics in it (in the property dialog for it the base class is flash.display.SimpleButton).

I want the user to be able to press the onscreen arrows OR the keyboard arrow keys to page forwards and backwards.

So…when I test the movie or publish it as an app, pressing the left and right keyboard keys doesn't do anything. HOWEVER…AFTER I click on the screen arrows THEN the keyboard events are getting picked up!!! How come my keyboard events are not getting received initially? Why does clicking on the onscreen buttons make the 'holder' start receiving the events?

UPDATE

I've also just commented out all of my code EXCEPT for the instantiating the 'holder' and adding the listener.
The KeyboardEvents are not being heard by the holder.

UPDATE…ANSWER

So I found out that if I want to globally hear the KeyboardEvent, I should register stage as the listener. So this did the trick:

stage.addEventListener(KeyboardEvent.KEY_UP, handleKeyboardEvent);

Info from Colin Moock's book:

Keyboard-input events that trigger
application-wide commands are
typically handled globally, by
listeners registered with Flash
Player's Stage instance. By contrast,
keyboard-input events that trigger a
specific interface-element response
are typically handled by listeners
registered with the object that
currently has keyboard focus.

So I guess that in my initial version, when I clicked on the onscreen arrow button, I somehow gave keyboard focus to the 'holder;.

Best Answer

Ususally the object you click on gets the focus. This really affects listeners, that's why it works when you add it to the stage.

When you clicked on any of those, your "holder" object got the focus, therefore the event fired. Now you do it well, that you added it to the stage.

Related Topic