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

时间:2011-02-02 22:33:17

标签: java events swing keylistener

我有一个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中注册任何东西,所以它不是为同一个击键注册其他东西。

4 个答案:

答案 0 :(得分:4)

只需更改您的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.CTRL_DOWN_MASK之外,指定KeyEvent.VK_CONTROL尤其重要。修改后的代码示例中缺少此特定详细信息。

答案 1 :(得分:2)

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

答案 2 :(得分:2)

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

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

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

答案 3 :(得分:1)

您可以使用Global Event Listener

相关问题