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

Java 侦听组件层次结构的关键事件,java,events,swing,keylistener,Java,Events,Swing,Keylistener,我有一个Swing应用程序,需要根据是否按下control或alt键来显示不同的控件集。我在主组件中添加了一个KeyListener,但是只有在选择了该组件时才会通知它,而不是在选择了子组件时。是否有方法侦听组件和所有子代的事件 编辑: 我尝试使用主组件的InputMap,但按下修改器键时不会触发任何事件。具体来说,我有以下代码: InputMap inputMap = panel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT

我有一个Swing应用程序,需要根据是否按下control或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中注册任何内容,因此它不像是为同一个键笔划注册了其他东西。

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

你可以考虑使用一些Swing组件。您可以使用
JComponent.WHEN\u FOCUSED\u COMPONENT
指定,以指示您希望在组件或其子组件处于焦点时响应给定的击键

如果不想使用InputMap或ActionMap,可以将KeyListener添加到所有子组件中:

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

您可能可以使用。

只需更改
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_FOCUSED_组件的祖先_)能够监听子部件和更深层的小部件是很重要的


在查找控件按键事件时,除了指定
KeyEvent.VK\u控件外,指定
KeyEvent.CTRL\u DOWN\u MASK
尤为重要。修改后的代码示例中缺少此特定细节。

这适用于“释放控制”按键,但不适用于“按下控制”。对于alt和shift,情况也是如此。@Adam Crum好的,有些控件可能正在侦听ctrl、alt或shift。但是,至少在测试其他按键时,它会在按键时启动给定的操作。不过,不可否认,当按下按键时,它会反复启动。Zack提到InputMap和ActionMap使用的是键绑定。再次检查教程,它会解决你的问题。不,教程不能解决我的问题。InputMap不适用于这种情况。我发现将按键更改为“ctrl pressed CONTROL”将响应控制键的按下,但还有另一个问题:我想知道何时按下控制键,而不管是否按下alt/altGr/shift/meta。如果不为我关心的每个修改器按键添加16个按键笔划,这是不可能的。我要说的是:@Adam Crum ok dok。但教程中的信息,无论是充满鳗鱼的气垫船还是我提供的信息,对未来都是很好的了解。祝你好运!我在使用聚焦组件时遇到了
问题,发现在聚焦窗口中使用
更有用。