Как мне назначить Enter как ключ триггера всех JButton в моем приложении Java? - PullRequest
12 голосов
/ 13 января 2009

Я пишу приложение на Java Swing с использованием внешнего вида Metal. Каждый раз, когда в моем приложении появляется JButton, пользователь использует клавишу Tab для перемещения фокуса на кнопку, а затем нажимает клавишу Enter Ничего не произошло! Если он нажимает клавишу пробела, запускаются события кнопки. Как назначить клавишу Enter для запуска тех же событий, что и клавиша пробела? Спасибо за вашу помощь.

Ответы [ 6 ]

17 голосов
/ 13 января 2009

Я нашел следующее:

http://tips4java.wordpress.com/2008/10/25/enter-key-and-button/

Где Роб Кэмик пишет, что при использовании JDK5 и более поздних версий вы просто добавляете ...

UIManager.put("Button.defaultButtonFollowsFocus", Boolean.TRUE);

... к приложению для решения проблемы. Это помогло мне! И я не могу представить ничего проще. Однако при использовании более старых версий Java вам нужно будет что-то, что Ричард и Питер описывают в своих ответах на этот вопрос.

4 голосов
/ 13 января 2009

Вот полный пример. Ричард был близок, но вам также нужно сопоставить нажатие клавиши ВВОД с действием, а не просто отпустить. Чтобы заставить это работать для ВСЕХ кнопок, я поместил это отображение в карту ввода по умолчанию для кнопок. Добавьте импорт, и он должен быть запущен.


public class Main implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Main());
    }

    @Override
    public void run() {
        setupEnterActionForAllButtons();

        JFrame frame = new JFrame("Button test");
        frame.getContentPane().add(createButton(), BorderLayout.NORTH);
        frame.getContentPane().add(createButton(), BorderLayout.SOUTH);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setVisible(true);
    }

    private void setupEnterActionForAllButtons() {
        InputMap im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
        Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
        Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));

        im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
        im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
    }

    private JButton createButton() {
        JButton b = new JButton("press enter");
        b.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println("Pressed");
            }
        });

        return b;
    }
}
1 голос
/ 14 января 2009

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

Обход "кнопка по умолчанию" работает, так как используемый вами L & F использует ввод для кнопки по умолчанию.

Временное решение Питера явно меняет стандартную клавишу L & F «действие фокуса» - что несколько более убедительно, если вы спросите меня.

Я бы добавил, что я не думаю, что многие пользователи захотят нажать на кнопку, а затем нажать клавишу ввода (большинство даже не заметят индикатор фокуса) - они хотят, чтобы действие по умолчанию было «правильным» и работало везде, где они нажимают ввод. Это можно сделать только с помощью входных карт, как предлагает Ричард.

Я бы, конечно, предложил получить очень четкое представление о том, чего на самом деле хотят и ожидают ваши пользователи (предпочтительно со ссылкой на другие приложения, которые они используют), прежде чем что-либо менять в глобальном масштабе.

0 голосов
/ 15 сентября 2015

Расширение для ответов выше, чтобы сделать то же самое с радио, флажки Вызывается это перед созданием компонентов

void setupEnterAction(String componentName){
    String keyName = componentName + ".focusInputMap";
    InputMap im = (InputMap) UIManager.getDefaults().get(keyName);
    Object pressedAction = im.get(KeyStroke.getKeyStroke("pressed SPACE"));
    Object releasedAction = im.get(KeyStroke.getKeyStroke("released SPACE"));
    im.put(KeyStroke.getKeyStroke("pressed ENTER"), pressedAction);
    im.put(KeyStroke.getKeyStroke("released ENTER"), releasedAction);
}

public void setEnterEvent(){
    setupEnterAction("Button");
    setupEnterAction("RadioButton");
    setupEnterAction("CheckBox");
}
0 голосов
/ 13 января 2009

Вы также можете установить «кнопку по умолчанию» для кнопки, которая была недавно сфокусирована.

Я сделал это с приложением, и все способы сделать это - кошмар для обслуживания и отладки. Дело в том, что это явно не то, что дизайнеры Swing намеревались осуществить.

0 голосов
/ 13 января 2009

Вы делаете это, назначая карту ввода / действия для клавиши Enter. Примерно так:

// save the command mapping for space
Object spaceMap = button.getInputMap.get(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true));
// add a mapping from enter to the same command.
button.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true),spaceMap); 
...