For some reason, the event listener I define never seems to receive any events, although I believe it should. Here's a very short description of the MXML code I'm using:
WindowedApplication
VBox (root box)
MenuBar
TabNavigator
VBox (first tab)
Canvas
VBox (second tab)
If I add a listener for KEY_DOWN events to WindowedApplication or the root VBox, the handler receives the events just fine. But if I add the listener to the Canvas or the first tab VBox, the handler never seems to receive any. (I assume here that just clicking on the Canvas area gives it focus - am I correct?)
I'm just starting out with Flex, so I'm hoping I made a silly beginner's mistake somewhere. I'd be very grateful for any help. Thanks!
Agree with Ryan, and I'd add that I've sometimes found it helpful, when handling keyboard events in general, to wire up my listeners to the event's capture phase, rather than the target or bubbling phases (note the third argument, false by default):
stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown, true);
Thinking for instance of a casual game in which the arrow keys control the core action somehow (Tetris, maybe -- rotate left, rotate right), responding to an event during the capture phase means can have distinct advantages. From the docs:
In the capturing phase, Flex examines
an event's ancestors in the display
list to see which ones are registered
as a listener for the event. Flex
starts with the root ancestor and
continues down the display list to the
direct ancestor of the target. In most
cases, the root ancestors are the
Stage, then the SystemManager, and
then the Application object.
So in this case, you can be sure the stage's listener will get the notification first, before anyone else, and can respond accordingly -- either by terminating the event-propagation entirely (sometimes you might want to do that) or by translating it into a more application-specific, custom event:
private function handleKeyDown(event:KeyboardEvent):void
{
if (event.keyCode == Keyboard.LEFT)
{
dispatchEvent(new Event("rotateLeft"));
}
else if (event.keyCode == Keyboard.RIGHT)
{
dispatchEvent(new Event("rotateRight"));
}
else
{
event.stopPropagation();
}
}
... and keeping you from peppering keyboard listeners all over your app.
Event-propagation phases are described in more detail here. Check it out as well -- there's great info in there that's well worth knowing.
you are wanting to know and catch a keydown event dispatched from the canvas? I would say that yes, you are probably having trouble with the canvas actually having focus. This link may help some:
http://livedocs.adobe.com/flex/3/html/help.html?content=Capturing_User_Input_3.html
Knowing what it is you are trying to achieve would help to give you a better solution. Why is it that you are wanting to catch keyboard events only on the canvas?