Как Java отправляет события KeyEvents?

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

Я отлаживал проблему привязки ключей (оказалось, что я использовал неправильное JComponent.WHEN _ * условие), и я наткнулся на краткую и веселую javadoc для частного пакета javax.swing.KeyboardManager (к сожалению) анонимным Java-инженером. помочь отправить действия клавиатуры для WHEN_IN_FOCUSED_WINDOW стиль действий. Действия с другими условиями обрабатывается непосредственно в JComponent.

Вот описание симантики [sic] о том, как диспетчер клавиатуры должен работать по крайней мере [так в оригинале], как я понимать это.

KeyEvents отправляются на сфокусированный компонент. Фокус-менеджер получает первую трещину при обработке этого мероприятие. Если менеджер фокуса не хотите, тогда JComponent вызывает super.processKeyEvent () это позволяет слушатели возможность осмыслить мероприятие.

Если никто из слушателей «не потребляет» событие, тогда сочетания клавиш получают выстрел. Вот где все начинается становится интересно. Во-первых, нажатие клавиш [sic] определяется с помощью WHEN_FOCUSED состояние получить шанс. Если ни один из они хотят событие, тогда компонент ходит, хотя это [sic] родители искал действия типа 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.)

9
задан Matthias Braun 6 December 2017 в 09:16
поделиться