Java如何分派KeyEvents?
我已经阅读了几次明确的教程,但我的大脑缓存似乎不够大,无法容纳复杂的过程 我在调试一个密钥绑定问题(结果是我使用了错误的Java如何分派KeyEvents?,java,swing,key-bindings,keyevent,Java,Swing,Key Bindings,Keyevent,我已经阅读了几次明确的教程,但我的大脑缓存似乎不够大,无法容纳复杂的过程 我在调试一个密钥绑定问题(结果是我使用了错误的JComponent.WHEN*条件),我偶然发现了一个简洁而有趣的javadoc,它是一个匿名Java工程师(不幸的是)为私有包编写的 我的问题是:除了在最开始检查的KeyEventDispatcher,描述是否遗漏和/或错误? KeyboardManager类用于 帮助为应用程序分派键盘操作 当以窗口样式操作为焦点时。 具有其他条件的操作是 直接在JComponent中处理
JComponent.WHEN*
条件),我偶然发现了一个简洁而有趣的javadoc,它是一个匿名Java工程师(不幸的是)为私有包编写的
我的问题是:除了在最开始检查的KeyEventDispatcher
,描述是否遗漏和/或错误?
KeyboardManager类用于
帮助为应用程序分派键盘操作
当以窗口样式操作为焦点时。
具有其他条件的操作是
直接在JComponent中处理
下面是对symantics的描述
[原文如此]键盘如何调度
至少应该像我一样工作
理解它
KeyEvents被发送到
重点部分。焦点管理器
在处理此文件时获取第一个裂纹
事件如果焦点管理器没有
想要它,JComponent就会调用它
super.processKeyEvent()这允许
听众有机会处理问题
事件
如果没有侦听器“消费”
然后,keybindings获得一个
射击。事情就是从这里开始的
变得有趣。首先,密钥
[sic]定义为当_聚焦时
我有机会。如果没有
他们想要的是事件,然后是
组件虽然是[sic]父母,但仍能行走
寻找类型的动作
当\u聚焦\u组件的\u祖先\u时
如果还没有人拿走它,那么它
在这里结束。然后我们寻找
为注册的组件
当窗口事件和火灾发生时
对他们来说。请注意,如果没有这些
找到后,我们将事件传递给
菜单栏,让他们有一个裂缝
看看吧。他们的处理方式不同
最后,我们检查一下我们是否在看
内部框架。如果我们是和否
一个人想要这个活动,然后我们继续前进
致内部框架的创建者,请参见
如果有人想参加这个活动(等等)
等等)
(更新)如果您曾经对《密钥绑定指南》中的此粗体警告感到疑惑,请执行以下操作: 因为搜索组件的顺序是不可预测的,在聚焦窗口绑定中避免重复强> 这是因为
键盘管理器#fireKeyboardAction
中的这一部分:
Object tmp = keyMap.get(ks);
if (tmp == null) {
// don't do anything
} else if ( tmp instanceof JComponent) {
...
} else if ( tmp instanceof Vector) { //more than one comp registered for this
Vector v = (Vector)tmp;
// There is no well defined order for WHEN_IN_FOCUSED_WINDOW
// bindings, but we give precedence to those bindings just
// added. This is done so that JMenus WHEN_IN_FOCUSED_WINDOW
// bindings are accessed before those of the JRootPane (they
// both have a WHEN_IN_FOCUSED_WINDOW binding for enter).
for (int counter = v.size() - 1; counter >= 0; counter--) {
JComponent c = (JComponent)v.elementAt(counter);
//System.out.println("Trying collision: " + c + " vector = "+ v.size());
if ( c.isShowing() && c.isEnabled() ) { // don't want to give these out
fireBinding(c, ks, e, pressed);
if (e.isConsumed())
return true;
}
}
所以搜索的顺序实际上是可预测的,但显然取决于这个特定的实现,所以最好不要依赖它。让它不可预测
(Javadoc和代码来自WinXP上的jdk1.6.0_b105。)我们需要从开始调试
只需阅读该方法的源注释,您就可以完全了解事件在Swing中如何流动(您也可以从EventQueue.pumpeventsforheirarch启动一个级别) 为了清楚起见,让我摘录一下代码:
现在,您可以将上述流程与您的描述进行匹配,以确定其是否正确。但关键是你不应该依赖私有类的Javadoc,原因是开发人员通常不关心在代码更改时更新私有类的注释,所以这些文档可能会过时。这是一个关于KeyEvent处理的很好的分析。。。但我不知道这是否真的是一个可以回答的问题。@BoffinbraiN:我希望有几十个挥杆徽章的人会说“据我所知,这是正确的”:)是的,那肯定会更好!但我认为,对于如此深刻的东西,它确实是特定于实现的,而且您比大多数勤奋的程序员更仔细地检查了这个实现当然,最好不要让你的代码依赖于这个特定的细节。如果你把它分解成一个问题和一个自我回答,这可能会更好。然后你可以接受你的答案或者让人们投票。+1代表“大脑缓存”。;-)