Я несколько раз читал конкретное руководство по привязкам клавиш , но мой мозговой кэш кажется недостаточно большим, чтобы содержать сложные процессы.
Я отлаживал проблему с привязкой ключа (оказалось, что я использовал неправильное условие JComponent.WHEN_*
), и наткнулся на краткий и веселый javadoc для пакета private javax.swing.KeyboardManager
от (к сожалению, ) анонимный инженер Java.
У меня такой вопрос: кроме KeyEventDispatcher
, который проверяется в самом начале, что-то упускает описание и / или ошибается?
Класс KeyboardManager используется для
помочь диспетчеризировать действия клавиатуры для
WHEN_IN_FOCUSED_WINDOW стиль действий.
Действия с другими условиями
обрабатывается непосредственно в JComponent.
Вот описание символики
[так] о том, как клавиатура диспетчеризации
должен работать по крайней мере [SIC], как я
понимать это.
Ключевые события отправляются на
сфокусированный компонент. Фокус менеджер
получает первую трещину при обработке этого
событие. Если менеджер фокуса не
хотите, тогда JComponent вызывает
super.processKeyEvent () это позволяет
слушатели шанс обработать
событие.
Если ни один из слушателей не "потребляет"
событие, то сочетания клавиш получают
выстрел. Это где вещи начинают
получить интересное. Во-первых, KeyStokes
[sic] определяется с помощью WHEN_FOCUSED
условие получить шанс. Если ни один из
они хотят событие, то
компонент идет, хотя это [так] родители
искал действия типа
WHEN_ANCESTOR_OF_FOCUSED_COMPONENT.
Если никто еще не взял его, то он
заводится здесь. Затем мы ищем
компоненты, зарегистрированные для
WHEN_IN_FOCUSED_WINDOW события и огонь
им. Обратите внимание, что если ни один из них
найдены, то мы передаем событие
менубары и пусть у них будет трещина
на него. Они обрабатываются по-разному.
Наконец, мы проверяем, смотрим ли мы на
внутренняя рама. Если мы и нет
один хотел событие, то мы движемся вверх
создателю InternalFrame и посмотреть
если кто-то хочет событие (и так далее
и так далее).
(ОБНОВЛЕНИЕ) Если вы когда-нибудь задумывались об этом смелом предупреждении в руководстве по привязке клавиш:
Поскольку порядок поиска компонентов непредсказуем, избегайте дублирования привязок WHEN_IN_FOCUSED_WINDOW!
Это из-за этого сегмента в KeyboardManager#fireKeyboardAction
:
Object tmp = keyMap.get(ks);
if (tmp == null) {
// don't do anything
} else if ( tmp instanceof JComponent) {
...
} else if ( tmp instanceof Vector) { //more than one comp registered for this
Vector v = (Vector)tmp;
// There is no well defined order for WHEN_IN_FOCUSED_WINDOW
// bindings, but we give precedence to those bindings just
// added. This is done so that JMenus WHEN_IN_FOCUSED_WINDOW
// bindings are accessed before those of the JRootPane (they
// both have a WHEN_IN_FOCUSED_WINDOW binding for enter).
for (int counter = v.size() - 1; counter >= 0; counter--) {
JComponent c = (JComponent)v.elementAt(counter);
//System.out.println("Trying collision: " + c + " vector = "+ v.size());
if ( c.isShowing() && c.isEnabled() ) { // don't want to give these out
fireBinding(c, ks, e, pressed);
if (e.isConsumed())
return true;
}
}
Таким образом, порядок поиска на самом деле предсказуем , но, очевидно, зависит от конкретной реализации, поэтому лучше , а не , чтобы полагаться на него вообще. Держите это непредсказуемым.
(Javadoc и код из jdk1.6.0_b105 на WinXP.)