Как изменить Nimbus L & F, чтобы активировать кнопку по умолчанию при нажатии клавиши Enter? - PullRequest
0 голосов
/ 03 марта 2011

В Nimbus L & F, когда человек нажимает клавишу Enter, если кнопка имеет фокус, эта кнопка нажимается независимо от того, была ли установлена ​​другая кнопка по умолчанию, как в:

getRootPane().setDefaultButton(myButton);

Кроме того, использование связывания клавиш не работает:

Action clickDefault = new AbstractAction("clickDefault") {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Got Here");
        getRootPane().getDefaultButton().doClick();
    }
};
InputMap im = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
KeyStroke enter = KeyStroke.getKeyStroke("ENTER");
im.put(enter, "defaultButton");
getRootPane().getActionMap().put("defaultButton", clickDefault);

Я даже не вижу сообщения "Got Here", хотя, если я связываюсь с другим KeyStroke, таким как "P", оно функционирует должным образом. Так что может показаться, что ключ Enter захватывается до того, как он попадет в этот обработчик событий.

Я также пытался изменить UIDefaults:

    im = (InputMap) UIManager.getDefaults().get("Button.focusInputMap");
    im.put(enter, null);
    im.put(enterRelease, null);

Это тоже не удалось. У кого-нибудь есть идеи, как этого добиться?

--- Обновление ---

Дальнейшие исследования показали, что InputMap для JButton содержит {"нажатый Enter": "нажатый", "освобожденный ENTER": "освобожденный"} (а также привязки для пробела). Привязка клавиш рассматриваемого компонента имеет более высокий приоритет, чем корневая панель. Смотрите мой ответ ниже для кода, который решает проблему.

Ответы [ 2 ]

0 голосов
/ 03 марта 2011

Хорошо, наконец-то разобрался, как заставить эту работу работать так, как я хотел. Вот код, который я использую:

public class Main {
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {

            // Use Nimbus if it's available and we're not on Mac OSX
            if (!System.getProperty("os.name").equals("Mac OS X")) {
                try {
                    for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                        if ("Nimbus".equals(info.getName())) {
                            UIManager.setLookAndFeel(info.getClassName());

                            ((InputMap) UIManager.get("Button.focusInputMap"))
                                    .put(KeyStroke.getKeyStroke("pressed ENTER"), null);
                            ((InputMap) UIManager.get("Button.focusInputMap"))
                                    .put(KeyStroke.getKeyStroke("released ENTER"), null);

                            break;
                        }
                    }
                } catch (Exception e) {
                    // Default Look and Feel will be used
                }
            }

            MainWindow mainWindow = new MainWindow();
            mainWindow.setVisible(true);
        }
    });
}

} // конец класса Main

Одна важная вещь, которую я выяснил, состояла в том, что обновления InputMap должны быть сделаны ПОСЛЕ настройки Look and Feel. Я не знал, что было необходимо, когда возился с этими вещами, но опять же, я новичок во всем этом бизнесе «Взгляд и Чувство».

0 голосов
/ 03 марта 2011

Я не использую Nimbus LAF, поэтому я не уверен, как он работает.

В Windows LAF кнопка по умолчанию автоматически изменится на кнопку, которая в данный момент имеет фокус. На это указывают более темные рамки на кнопке, которая имеет фокус. Если фокус не на кнопке, более темная граница будет сброшена на кнопку по умолчанию.

В Windows вы можете отключить это поведение с помощью:

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

Теперь более темная граница останется на кнопке по умолчанию, а клавиша Enter активирует кнопку по умолчанию. На кнопку с фокусом все еще можно нажать, используя пробел.

...