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