Keymap,InputMap,ActionMap,KeyListener – 选择重载
我无法找到关于所有这些之间关系的简明回答,以便我可以选择最佳实践并继续前进。 JTextComponent
具有:
-
旧的
addKeyListener(..)
。 我们编写一个KeyListener
,其方法可以在keyPressed(..)
,keyTyped(..)
等事件上调用,我们可以查询:event.getKeyCode()
。 -
addKeymap(..)
和setKeymap(..)
。Keymap
有addActionForKeyStroke(..)
,它接受KeyStroke
(我们可以通过调用指定字符或键代码的KeyStroke
的静态方法获得)和Action
,它是一个带有铃声和口哨声的ActionListener
。 -
getInputMap(..)
和getActionMap(..)
。InputMap
将KeyStroke
(如上所示)映射到String
,ActionMap
将字符串映射到Action
(如上所述)。 Java教程如何使用键绑定来讨论这个问题。
这是实现相同function的三种冗余方式。 除了比较优势/劣势之外,这还提出了这三种机制如何共存的自然问题? 哪些优先于其他?
-
InputMap
+ActionMap
系统在1.3中引入并替换了旧的Keymap
(为了向后兼容性,它使用了引擎盖下的InputMap
+ActionMap
系统重新实现)。 新系统具有Keymap
function的超集。 (摘自Loy和Eckstein撰写的O’Reilly书籍Java Swing , 第755页 。) -
因此,我们不需要担心新代码的
Keymap
。 -
如何使用键绑定的Java教程甚至没有提到
Keymap
,但它确实解决了KeyListener
与键绑定 (即InputMap
+ActionMap
工具):-
由于焦点和组件包含层次结构(它不知道)的问题,
KeyListener
的方法需要更多的工作。 例如,如果我们有一个表组件和一个包含焦点的table-cell组件,按下↑键会将事件发送到表格单元组件,我们可以将它们传递给表格(因为我们想要更改表格当前选中的单元格。 -
相反,键绑定允许我们直接在父组件上指定绑定:每个
JComponent
都有三个InputMap
和一个ActionMap
。 输入映射具有以下类型:JComponent.WHEN_FOCUSED
,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
和WHEN_IN_FOCUSED_WINDOW
。 与侦听器不同,其中焦点组件上的所有KeyListener
仅按顺序处理,通过键绑定,事件将在层次结构中向上传播(嗯,我认为树,因为每个组件只有一个父组件),直到找到一个动作(尚未被禁用),即停止时。 在此搜索期间,第二种类型的InputMap
优先于第三种类型。 -
KeyListener
优先于键绑定机制。 在处理组件的KeyListener
,其中一个可能是e.consume()
,然后事件将不会到达更多的KeyListener
,也不会到达键绑定层次结构。 首先处理最后添加的键侦听器。
-
-
因此,虽然键绑定方法从头开始设置需要更多麻烦(您必须给
Action
一个名称,并调用两个方法通过InputMap
将它绑定到KeyStroke
和通过ActionMap
将它绑定到AbstractAction
),它似乎它应该是分配一个函数来响应按键的第一个调用点。KeyListener
使您能够做更多事情(例如奇异的键组合 – 超出KeyStroke
可以处理的范围;允许更早访问键事件,能够e.consume()
它),但键绑定更方便,预测基本用例就像他们一样。
相关问题(由相关问题建议)是处理文本组件的另一种冗余机制,特别是: DocumentListener
和DocumentFilter
。 当重新映射键的原因是控制文本组件中的文本发生什么时,这些更加方便和缺陷。
另请参阅:有关密钥绑定系统从引入时归档版本的详细信息的报告。