title: How does Java dispatch KeyEvents?
body: <p>I've read the definite tutorial on <a href="http://download.oracle.com/javase/tutorial/uiswing/misc/keybinding.html" rel="nofollow noreferrer">key bindings</a> a few times, but my brain cache doesn't seem large enough to hold the complicated processes.</p>
  
  <p>I was debugging a key binding problem (turned out I was using the wrong <code>JComponent.WHEN_*</code> condition), and I stumbled upon a concise and hilarious javadoc for the package private <a href="http://kickjava.com/src/javax/swing/KeyboardManager.java.htm" rel="nofollow noreferrer"><code>javax.swing.KeyboardManager</code></a> by an (unfortunately) anonymous Java engineer.</p>
  
  <p>My question is this: except for <code>KeyEventDispatcher</code> which is checked at the very beginning, <strong>does the description miss and/or mistake anything?</strong></p>
  
  <blockquote>
    <p>The KeyboardManager class is used to
    help dispatch keyboard actions for the
    WHEN_IN_FOCUSED_WINDOW style actions.
    Actions with other conditions are
    handled directly in JComponent. </p>
    
    <p>Here's a description of the symantics
    [sic] of how keyboard dispatching
    should work atleast [sic] as I
    understand it. </p>
    
    <p>KeyEvents are dispatched to the
    focused component. The focus manager
    gets first crack at processing this
    event. If the focus manager doesn't
    want it, then the JComponent calls
    super.processKeyEvent() this allows
    listeners a chance to process the
    event. </p>
    
    <p>If none of the listeners "consumes"
    the event then the keybindings get a
    shot. This is where things start to
    get interesting. First, KeyStokes
    [sic] defined with the WHEN_FOCUSED
    condition get a chance. If none of
    these want the event, then the
    component walks though it's [sic] parents
    looked for actions of type
    WHEN_ANCESTOR_OF_FOCUSED_COMPONENT. </p>
    
    <p>If no one has taken it yet, then it
    winds up here. We then look for
    components registered for
    WHEN_IN_FOCUSED_WINDOW events and fire
    to them. Note that if none of those
    are found then we pass the event to
    the menubars and let them have a crack
    at it. They're handled differently. </p>
    
    <p>Lastly, we check if we're looking at
    an internal frame. If we are and no
    one wanted the event then we move up
    to the InternalFrame's creator and see
    if anyone wants the event (and so on
    and so on).</p>
  </blockquote>
  
  <hr>
  
  <p>(UPDATE) If you've ever wondered about this bold warning in the key bindings guide:</p>
  
  <blockquote>
    <p>Because the order of searching the components is unpredictable, <strong>avoid duplicate WHEN_IN_FOCUSED_WINDOW bindings!</strong></p>
  </blockquote>
  
  <p>It's because of this segment in <code>KeyboardManager#fireKeyboardAction</code>:</p>
  
  <pre><code>     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 &gt;= 0; counter--) {
           JComponent c = (JComponent)v.elementAt(counter);
           //System.out.println("Trying collision: " + c + " vector = "+ v.size());
           if ( c.isShowing() &amp;&amp; c.isEnabled() ) { // don't want to give these out
               fireBinding(c, ks, e, pressed);
           if (e.isConsumed())
               return true;
           }
       }
  </code></pre>
  
  <p>So the order of searching is actually <em>predictable</em>, but obviously dependent on this particular implementation, so it's better <em>not</em> to rely on it at all. Keep it unpredictable.</p>
  
  <p>(Javadoc and code is from jdk1.6.0_b105 on WinXP.)</p>