Как заставить кнопку глубоко во вложенной панели Swing получить «фокус клавиатуры»? - PullRequest
0 голосов
/ 10 июля 2009

У меня есть поворотная рама, которая содержит встроенные панели, содержащие другие панели и т. Д. В глубине есть кнопка. Я хочу, чтобы кнопка получила фокус, чтобы нажатие клавиши «Ввод» генерировало событие actionPerformed.

Однако, если я выполняю myButton.requestFocus () или myButton.requestFocusInWindow (), все окно получает фокус, но, похоже, ничего не происходит с точки зрения клавиатуры.

Я явно что-то упускаю из подсистемы фокуса.

Обновление 2: я явно добавил KeyListener в дополнение к ActionListener, и теперь он работает. Это действительно странно, так как я думал, что actionListener включает в себя действия как клавиш, так и мыши.

Ответы [ 6 ]

1 голос
/ 10 июля 2009

Чтобы клавиша ввода работала, вы, вероятно, захотите установить кнопку по умолчанию, а не фокус клавиатуры:

button.getRootPane().setDefaultButton(button);

Если вы действительно хотите сфокусироваться на клавиатуре, ваша проблема может быть связана с тем, когда вы вызываете requestFocus. Иногда, если он вызывается до того, как компонент полностью виден, его можно игнорировать. Чтобы исправить это, вы можете отложить вызов requestFocus до тех пор, пока не будут обработаны другие события:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        button.requestFocus();
    }
});
0 голосов
/ 10 июля 2009

Вы можете получить корневую панель фрейма и обновить inputMap и actionMap. См. Код ниже.

InputMap map = getRootPane (). GetInputMap (JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); map.put (KeyStroke.getKeyStroke (KeyEvent.VK_ENTER, 0), "ok");

ActionMap actionMap = getRootPane (). GetActionMap ();
actionMap.put ("ok", enterAction);

Здесь enterAction - это объект AbstractAction, действие которого actionPerformed () будет вызвано, когда пользователь нажмет Enter.

0 голосов
/ 10 июля 2009

Я хочу, чтобы кнопка фокусировалась так, чтобы нажатие клавиши «Ввод» будет создать событие actionPerformed.

Зависимые лица LAF. Enter работает в Windows, но не в Metal LAF. Проверьте Введите ключ и кнопку для получения дополнительной информации.

Метод requestFocusInWindow () работает только в том случае, если компонент в данный момент виден в кадре. Других уловок нет, поэтому мы просто делаем случайные предположения о том, что вы делаете неправильно. Если вам нужна дополнительная помощь, вы должны опубликовать SSCCE , демонстрирующий проблему.

0 голосов
/ 10 июля 2009

Во-первых, не используйте requestFocus (), используйте requestFocusInWindow () . У requestFocus есть специфичные для платформы проблемы, а requestFocusInWindow более последовательный.

Ваша актуальная проблема; Компонент (или один из его родителей), вероятно, не виден или не отображает фокус.

0 голосов
/ 10 июля 2009

Существует способ программно указать функциональность вкладки (вы знаете, когда вы нажимаете вкладку и выбирается следующий виджет)

По умолчанию используется способ добавления компонентов.

Использование этого пользовательского механизма позволит вам выбрать вложенную кнопку в качестве первой, которая получит событие actionperformed.

К сожалению, я не помню, как называется этот «механизм», но это что-то вроде обхода или обхода фокуса

0 голосов
/ 10 июля 2009

Похоже, что requestFocus () не работает на каком-то уровне. Попробуйте проверить, не может ли какой-либо из родительских jPanels или других компонентов запросить фокус, и постарайтесь найти причину проблемы.

...