Java Swing: показать нажатую кнопку при использовании соответствующей кнопки клавиатуры

Я делаю программу на Java, используя Swing, с графическим интерфейсом, который содержит клавиши со стрелками. Клавиши со стрелками соответствуют клавишам со стрелками на клавиатуре.

Когда я нажимаю клавишу со стрелкой вверх на клавиатуре, я бы хотел, чтобы клавиша со стрелкой вверх в графическом интерфейсе отображалась как нажатая. Пока я не отпущу клавишу со стрелкой, она должна показывать, что она все еще нажата, а при отпускании она также должна быть отпущена.

Фрагмент моего кода на данный момент (только для кнопки «Вверх»), который, я думаю, совершенно неверен в категории нажатого шоу:

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

person Sven    schedule 20.10.2012    source источник
comment
Да, конечно, мои извинения. Часто, когда я получаю пригодный для использования ответ, я слишком спешу его использовать. Я прошу прощения за это.   -  person Sven    schedule 20.10.2012
comment
1) Возможно, для этого рассмотрите привязки клавиш. 2) Чтобы быстрее получить помощь, опубликуйте SSCCE. 3) Хороший призыв заняться этим другим вопросом. :)   -  person Andrew Thompson    schedule 20.10.2012


Ответы (2)


Использование keyBindings (как уже упоминал @trashgod) — это лучший путь. Чтобы получить точно такое же визуальное поведение, как если бы активировать кнопку пробелом/вводом (когда она была сфокусирована)

  • реализовать действия, которые делегируют действия кнопки по умолчанию, зарегистрированные для нажатия/отпускания
  • нуждается в привязке к нажатой и отпущенной клавише для имитации
  • установить привязку к родителю кнопок в его inputMap типа WHEN_ANCESTOR

В коде:

// 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));
}
person kleopatra    schedule 20.10.2012
comment
+1 за делегирование, что позволяет избежать прямого манипулирования моделью кнопки. - person trashgod; 20.10.2012

Этот LinePanel использует Привязки клавиш и вызывает doClick() в actionPerformed() для достижения эффекта, подобного описанному вами.

Приложение: Поскольку вы хотите, чтобы кнопка отображалась нажатой, пока нажата клавиша, вы можете использовать необязательный параметр onKeyReleased для KeyStroke.getKeyStroke(). Как описано в ButtonModel, вам нужно будет сделать модель и вооруженной, и нажатой, чтобы имитировать нажатие мыши на кнопку.

person trashgod    schedule 20.10.2012