1

出于某种原因,我定义的事件侦听器似乎从不接收任何事件,尽管我相信它应该。这是我正在使用的 MXML 代码的简短描述:

WindowedApplication
    VBox (root box)
        MenuBar
        TabNavigator
            VBox (first tab)
                Canvas
            VBox (second tab)

如果我将 KEY_DOWN 事件的侦听器添加到 WindowedApplication 或根 VBox,则处理程序会很好地接收事件。但是,如果我将侦听器添加到 Canvas 或第一个选项卡 VBox,则处理程序似乎永远不会收到任何内容。(我在这里假设只需单击 Canvas 区域即可获得焦点 - 我是否正确?)

我刚刚开始使用 Flex,所以我希望我在某个地方犯了一个愚蠢的初学者错误。我将非常感谢任何帮助。谢谢!

4

2 回答 2

1

您想知道并捕捉从画布发送的 keydown 事件吗?我会说是的,你可能在画布实际上有焦点时遇到了麻烦。此链接可能会有所帮助:

http://livedocs.adobe.com/flex/3/html/help.html?content=Capturing_User_Input_3.html

了解您要达到的目标将有助于为您提供更好的解决方案。为什么您只想在画布上捕捉键盘事件?

于 2009-02-06T02:11:37.830 回答
1

同意 Ryan,我要补充一点,在处理一般键盘事件时,我有时会发现它很有帮助,将我的侦听器连接到事件的捕获阶段,而不是目标或冒泡阶段(注意第三个参数,false默认情况下):

stage.addEventListener(KeyboardEvent.KEY_DOWN, handleKeyDown, true);

考虑一个休闲游戏的例子,其中箭头键以某种方式控制核心动作(俄罗斯方块,也许——向左旋转,向右旋转),在捕获阶段响应事件意味着可以具有明显的优势。从文档:

在捕获阶段,Flex 在显示列表中检查事件的祖先,以查看哪些被注册为事件的侦听器。Flex 从根祖先开始,然后在显示列表中继续向下到目标的直接祖先。在大多数情况下,根祖先是 Stage,然后是 SystemManager,然后是 Application 对象。

因此,在这种情况下,您可以确保舞台的侦听器会先于其他任何人收到通知,并且可以做出相应的响应——通过完全终止事件传播(有时您可能想要这样做)或将其转换为更特定于应用程序的自定义事件:

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();
    }
}   

...并防止您在您的应用程序中使用键盘侦听器。

此处更详细地描述了事件传播阶段。也检查一下 - 那里有很多值得了解的信息。

于 2009-02-06T19:27:43.980 回答