侦听组件层次结构的关键事件

我有一个Swing应用程序,需要根据是否按下控制键或alt键显示不同的控件组。 我向主组件添加了一个KeyListener,但只有在选择了该组件时才通知它,而不是在选择了一个子组件时。 有没有办法听取组件和所有后代的事件?

编辑:

我尝试使用主要组件的InputMap,但按下修饰键时不会触发任何事件。 具体来说,我有以下代码:

InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke("pressed CONTROL"), "test1"); inputMap.put(KeyStroke.getKeyStroke("released CONTROL"), "test2"); ActionMap actionMap = panel.getActionMap(); actionMap.put("test1", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("pressed"); } }); actionMap.put("test2", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("released"); } }); 

按下并释放控制键时,将打印“已释放”但未“按下”。 没有其他任何东西在任何InputMap中注册任何东西,所以它不像其他东西注册了相同的键击。

只需更改你的getKeyStroke(...)调用:

 InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, KeyEvent.CTRL_DOWN_MASK, false), "test1"); inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_CONTROL, 0, true), "test2"); ActionMap actionMap = panel.getActionMap(); actionMap.put("test1", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("pressed"); } }); actionMap.put("test2", new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("released"); } }); 

我带了很多试验和错误来提出正确的咒语。

使用getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)非常重要,以便能够收听子级和更深层次的小部件。

在查找控制键PRESS事件时,除了KeyEvent.VK_CONTROL之外,指定KeyEvent.CTRL_DOWN_MASK尤其重要。 修改后的代码示例中缺少此特定详细信息。

您可能希望尝试使用键绑定而不是KeyListeners。 键绑定是一个更高级别的构造,即使“侦听”的组件没有焦点,也可以侦听按键,而不是KeyListeners。 您可以在Swing教程中找到更多相关内容: 如何使用键绑定

您可以考虑使用某些swing组件的InputMap和ActionMap 。 您可以使用JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT指定,以指示您希望在组件或其子组件处于焦点时响应给定的击键。

如果您不想使用InputMap或ActionMap,只需将KeyListener添加到所有子组件:

 for (Component child : parent.getComponents()) { child.addKeyListener(keyListener); } 

您可以使用全局事件侦听器 。