Java Swing:使用相应的键盘按钮时显示按下的按钮

我正在使用Swing创建一个Java程序,其中包含一个包含箭头键的GUI。 箭头键对应键盘上的箭头键。

当我按下键盘上的向上箭头键时,我希望GUI上的向上箭头键显示为按下。 在我释放箭头键之前,它应该显示它仍然被按下,并且在释放时它也应该释放。

到目前为止我的代码片段(仅针对Up按钮),我认为在按下类别的节目中是完全错误的:

... if (e.getKeyCode() == KeyEvent.VK_UP) { actionArrowUp(); JButton buttonUp = (JButton) mainTab.getComponent(4); buttonUp.setSelected(true); } ... @Override public void keyReleased(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) actionArrowUpRelease(); buttonUp.setSelected(true); 

使用keyBindings(如已经提到的@trashgod)是要走路。 获得完全相同的视觉行为,就像用空格/输入激活按钮一样(当它被聚焦时)

  • 实现委托给按下/释放注册的按钮默认动作的动作
  • 需要绑定到按下和释放键来模拟
  • 在WHEN_ANCESTOR类型的inputMap中将绑定安装到按钮的父级

在代码中:

 // the delegating action public static class SimulateButtonAction extends AbstractAction { AbstractButton button; public SimulateButtonAction(AbstractButton model, String fire) { super(fire); this.button = model; } @Override public void actionPerformed(ActionEvent e) { Action delegate = button.getActionMap().get(getName()); delegate.actionPerformed(new ActionEvent(button, ActionEvent.ACTION_PERFORMED, getName())); } public String getName() { return (String) getValue(Action.NAME); } } // example usage JComponent content = new JPanel(new GridLayout(0, 5)); Action log = new AbstractAction() { @Override public void actionPerformed(ActionEvent e) { System.out.println("triggered: " + ((AbstractButton) e.getSource()).getText()); } }; String pressed = "pressed"; String released = "released"; ActionMap actionMap = content.getActionMap(); InputMap inputMap = content.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); String[] arrows = {"UP", "DOWN", "LEFT", "RIGHT"}; for (int i = 0; i < arrows.length; i++) { JButton button = new JButton(log); button.setAction(log); button.setText(arrows[i]); content.add(button); // simulate pressed String pressedKey = pressed + arrows[i]; inputMap.put(KeyStroke.getKeyStroke(arrows[i]), pressedKey); actionMap.put(pressedKey, new SimulateButtonAction(button, pressed)); String releasedKey = released + arrows[i]; inputMap.put(KeyStroke.getKeyStroke(released + " " +arrows[i]), releasedKey); actionMap.put(releasedKey, new SimulateButtonAction(button, released)); } 

LinePanel使用键绑定并在actionPerformed()调用doClick() actionPerformed()以实现与您描述的效果类似的效果。

附录:如果您希望在按下按键时按下按钮,您可以使用KeyStroke.getKeyStroke()的可选onKeyReleased参数。 如ButtonModel ,您需要使模型既设防又按下以在按钮中模拟鼠标。