Java Swing: Show pressed button when using corresponding keyboard button

廉价感情. 提交于 2019-12-07 06:01:16

问题


I'm making a program in Java, using Swing, with a GUI that contains arrow keys. The arrow keys correspond to the arrow keys on the keyboard.

When I press the up arrow key on the keyboard, I'd like the up arrow key on the GUI to show up as being pressed. Until I release the arrow key, it should show it is still being pressed, and when released it should also release.

A snippet of my code so far (only for the Up button), which I think is totally wrong in the show being pressed category:

...
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:


Using keyBindings (as @trashgod already mentioned) is the way to go. To get the exact same visual behaviour as if activating the button by space/enter (when it were focused)

  • implement actions that delegate to the button's default actions registered for pressed/released
  • needs binding to both pressed and released of the key to simulate
  • install the binding to the buttons's parent in its inputMap of type WHEN_ANCESTOR

In code:

// 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));
}



回答2:


This LinePanel uses Key Bindings and invokes doClick() in actionPerformed() to achieve an effect similar to the one you describe.

Addendum: As you want the button to appear pressed while the key is pressed, you may be able to use the optional onKeyReleased parameter of KeyStroke.getKeyStroke(). As described in ButtonModel, you'll need to make the model both armed and pressed to simulate a mouse down in the button.



来源:https://stackoverflow.com/questions/12987557/java-swing-show-pressed-button-when-using-corresponding-keyboard-button

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!