захват глобальных нажатий клавиш в Java
Вопрос
Итак, я хочу запускать событие (приостановка / распаковка некоторых носителей) всякий раз, когда пользователь нажимает пробел в любом месте приложения my Swing.
Поскольку существует так много элементов управления и панелей, которые могли бы иметь фокус, на самом деле невозможно добавить ключевые события ко всем из них (не говоря уже о грубых).
Итак, я нашел
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher()
что удивительно, вы можете зарегистрировать глобальные предварительные обработчики нажатий клавиш.Однако есть серьезная проблема - пробелы будут вводиться все время в полях ввода, ячейках таблицы и т.д., и я, очевидно, не хочу тогда запускать событие pause!
Итак, есть какие-нибудь идеи?Возможно, есть способ глобально определить, сфокусирован ли курсор на чем-то, что позволяет вводить текст, без необходимости просматривать список всех редактируемых элементов управления (рвота!)?
Решение
Я думаю, что вы сами на это ответили - да, я думаю, что вы можете узнать текущий элемент, который имеет фокус, и, если это экземпляр определенного класса поля, вы игнорируете пространство с целью события паузы. Если это кажется серьезным, не беспокойтесь, instanceof ОЧЕНЬ быстр для JVM (и в любом случае вы говорите о событиях человеческого масштаба, которые являются эоном для процессора).
Другие советы
Я зациклен на своем Swing, но я думаю, что вы должны попробовать зарегистрировать глобального слушателя, используя Toolkit.addAWTEventListener с KEY_EVENT_MASK
. Затем вы можете отфильтровать обработку AWTEvent на основе ее типа и источника. Р>
ОК...Ну, я пытаюсь отфильтровать на основе источника.Проблема в моих редактируемых выпадающих списках...Они являются экземплярами
javax.swing.plaf.basic.BasicComboBoxEditor$BorderlessTextField
И поскольку borderlessstextfield является частным внутренним классом, я, очевидно, не могу выполнить проверку instanceof по нему.
идеи?
Редактировать:хорошо, значит, это работает....
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor(new KeyEventPostProcessor() {
public boolean postProcessKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
Object s = e.getComponent();
if (!(s instanceof JTextField) &&
!(s instanceof JTable && ((JTable) s).isEditing())
) {
music_player.pauseEvent();
}
//System.out.println(s.getClass().toString());
}
return true;
}
});
Это совершенно отвратительно, и я это ненавижу.Хотел бы я найти способ проверить, было ли нажатие клавиши использовано каким-либо компонентом - тогда я мог бы выполнить событие pause только тогда, когда нажатие клавиши не было вызвано каким-либо компонентом.