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