【问题标题】:Java Swing: Show pressed button when using corresponding keyboard buttonJava Swing:使用相应的键盘按钮时显示按下的按钮
【发布时间】:2012-10-10 20:29:09
【问题描述】:

我正在用 Java 编写一个程序,使用 Swing,带有一个包含箭头键的 GUI。方向键对应键盘上的方向键。

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

到目前为止我的代码的一个 sn-p(仅适用于向上按钮),我认为这在被按下的节目类别中是完全错误的:

...
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);

【问题讨论】:

  • 是的,当然,我很抱歉。通常,当我收到一个有用的答案时,我有点太仓促和无法使用它。对此我深表歉意。
  • 1) 或许可以考虑Key Bindings。 2) 为了尽快获得更好的帮助,请发布SSCCE。 3)很好的呼吁关注其他问题。 :)

标签: java swing button actionlistener key-bindings


【解决方案1】:

使用 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));
}

【讨论】:

  • +1 用于委托,避免了直接操作按钮的模型。
【解决方案2】:

这个LinePanel 使用Key Bindings 并在actionPerformed() 中调用doClick() 以达到类似于您描述的效果。

附录:当您希望按钮在按下时显示为按下,您可以使用KeyStroke.getKeyStroke() 的可选onKeyReleased 参数。如ButtonModel 中所述,您需要使模型同时启用并按下以模拟鼠标按下按钮。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-25
    • 2015-10-01
    • 1970-01-01
    • 2015-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    相关资源
    最近更新 更多