Pregunta

He leído el tutorial definitivo en asociaciones de teclas un par de veces, pero mi caché cerebro no parecen lo suficientemente grande para contener los procesos complicados.

Me depurando una asignación de teclas (resultó que estaba usando la condición JComponent.WHEN_* mal), y me topé con un conciso y javadoc hilarante para el paquete privado javax.swing.KeyboardManager por una (por desgracia) ingeniero anónimo Java.

Mi pregunta es la siguiente: a excepción de KeyEventDispatcher que se comprueba al principio, hace la descripción fallo y / o error nada

?
  

La clase KeyboardManager se utiliza para   las acciones del teclado ayuda para el despacho   acciones WHEN_IN_FOCUSED_WINDOW estilo.   Acciones con las demás condiciones son   manipulado directamente en JComponent.

     

He aquí una descripción de las symantics   [Sic] de cómo despacho teclado   debería funcionar al menos [sic] como yo   entiendelo.

     

KeyEvents se envían a la   componente centrado. El gestor de selección   obtiene primera grieta en la tramitación del presente   evento. Si el gestor de selección no lo hace   lo quiere, entonces las llamadas JComponent   super.processKeyEvent () esto permite   oyentes la oportunidad de procesar la   evento.

     

Si ninguno de los oyentes "consume"   el evento, las combinaciones de teclas obtener una   Disparo. Aquí es donde las cosas empiezan a   ponerse interesante. En primer lugar, keystokes   [Sic] definido con la WHEN_FOCUSED   condición tienen la oportunidad. Si ninguno de   éstos quieren el caso, entonces el   camina componente A pesar de que los padres de [sic]   buscado acciones de tipo   WHEN_ANCESTOR_OF_FOCUSED_COMPONENT.

     

Si no se ha tomado todavía, entonces   vientos de hasta aquí. a continuación, buscamos   componentes registrado para   WHEN_IN_FOCUSED_WINDOW eventos y fuego   a ellos. Tenga en cuenta que si ninguno de los   se encuentran a continuación, se pasa el caso a   las barras de menú y dejar que ellos tienen una grieta   en ella. Están manejan de forma diferente.

     

Por último, comprobamos si estamos mirando   un marco interno. Si somos y sin   uno quería el evento, nos movemos hacia arriba   al creador y sede de la InternalFrame   si alguien quiere el evento (y así sucesivamente   y así sucesivamente).


(UPDATE) Si alguna vez se ha preguntado sobre esta advertencia en negrita en la guía de asociaciones de teclas:

  

Debido a que el fin de buscar los componentes es impredecible, duplicado evitar atascamientos WHEN_IN_FOCUSED_WINDOW!

Es debido a este segmento en 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;
         }
     }

Así que el orden de búsqueda es en realidad predecible , pero depende obviamente en esta implementación particular, por lo que es mejor no a confiar en él en absoluto. Mantenerlo impredecible.

(Javadoc y el código es de jdk1.6.0_b105 en WinXP.)

¿Fue útil?

Solución

Tenemos que empezar la depuración de Component.dispatchEventImpl .
Sólo la lectura a través de los comentarios de código del método debe darle la idea perfecta de cómo fluyen los eventos de oscilación (también se puede empezar a un nivel por encima de EventQueue.pumpEventsForHeirarchy).

Para mayor claridad, házmelo dar un extracto del código:

  1. Establecer fecha y hora y modificadores de evento actual .; Pre-despachadores. Hacer cualquier reorientación necesaria / reordenación de aquí antes de que notificamos AWTEventListeners.
  2. Permitir que el Toolkit para pasar este evento para AWTEventListeners.
  3. Si nadie ha consumido un evento clave, permitir que el KeyboardFocusManager procesarlo.
  4. Permitir métodos de entrada para procesar el evento
  5. Pre-procesar los eventos especiales antes de la entrega
  6. Deliver eventos para el procesamiento normal
  7. manipulación
  8. Especial para 4061116: Gancho de explorador para cerrar los cuadros de diálogo modales:.)
  9. Permitir que el peer para procesar el evento. Excepto KeyEvents, que serán procesadas por el par después de que todos KeyEventPostProcessors (ver DefaultKeyboardFocusManager.dispatchKeyEvent ())

Ahora se puede coincidir con el flujo anterior con su descripción para determinar si su derecho o no. Pero el punto es que realmente no debería depender javadocs de clases particulares, la razón es que los desarrolladores de atención normalmente te para actualizar los comentarios de clases particulares cuando los cambios de código, por lo que los documentos pueden llegar a ser obsoletos.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top