Comment Java KeyEvents expédier?
-
30-09-2019 - |
Question
J'ai lu le tutoriel défini sur raccourcis clavier quelques fois, mais le cache de mon cerveau ne semble pas assez grand pour contenir les processus complexes.
je le débogage d'un problème de liaison clé (tourné que j'utilisais le mauvais état de JComponent.WHEN_*
), et je suis tombé sur un concis et javadoc hilarant pour le privé paquet javax.swing.KeyboardManager
par un (malheureusement) ingénieur Java anonyme.
Ma question est la suivante: à l'exception de KeyEventDispatcher
qui est vérifié au début, fait la miss description et / ou quoi que ce soit erreur
La classe KeyboardManager est utilisé pour aide dispatch du clavier pour la actions WHEN_IN_FOCUSED_WINDOW style. Les actions avec d'autres conditions sont traitée directement dans JComponent.
Voici une description des symantics [Sic] de la façon dont dispatching du clavier devrait travailler atleast [sic] que je le comprendre.
KeyEvents sont envoyésà la composante ciblée. Le gestionnaire de mise au point obtient la première fissure à traiter ce un événement. Si le gestionnaire de mise au point ne voulez, puis les appels JComponent super.processKeyEvent () ce qui permet auditeurs une chance de traiter les un événement.
Si aucun des auditeurs « consume » l'événement alors les raccourcis clavier obtenir un coup. C'est là que les choses commencent à devenir intéressant. Tout d'abord, keystokes [Sic] défini par la WHEN_FOCUSED état avoir une chance. Si aucun des ceux-ci veulent l'événement, le composante marche si elle ses parents [sic] cherché actions de type WHEN_ANCESTOR_OF_FOCUSED_COMPONENT.
Si personne ne l'a pris encore, il vents ici. Nous examinons ensuite pour composants enregistrés pour WHEN_IN_FOCUSED_WINDOW événements et le feu pour eux. Notez que si aucune de ces se trouvent alors nous passons l'événement les barres de menus et de leur laisser une fissure à elle. Ils sont traités différemment.
Enfin, nous vérifions si nous regardons un cadre interne. Si nous sommes et pas on voulait l'événement nous remontons au créateur et voir le InternalFrame si quelqu'un veut l'événement (et ainsi de suite et ainsi de suite).
(UPDATE) Si vous avez déjà demandé cet avertissement gras dans le guide des raccourcis clavier:
Parce que l'ordre de recherche des composants est imprévisible, éviter double WHEN_IN_FOCUSED_WINDOW fixations!
Il est à cause de ce segment dans 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;
}
}
l'ordre de recherche est en fait prévisible , mais dépend évidemment de cette mise en œuvre particulière, donc il vaut mieux pas pour compter sur elle du tout. Gardez imprévisible.
(Javadoc et le code est de jdk1.6.0_b105 sur WinXP).
La solution
Nous devons commencer le débogage Component.dispatchEventImpl . Just lecture à travers les commentaires de la source de la méthode devrait vous donner l'idée parfaite de la façon dont les événements de flux Swing (vous pouvez aussi commencer à un niveau supérieur de EventQueue.pumpEventsForHeirarchy).
Pour plus de clarté me laisser donner un extrait du code:
- Définir l'horodatage et des modificateurs de l'événement en cours .; Pré-répartiteurs. Effectuez l'une reciblage nécessaire / réordonnancement ici avant d'informer AWTEventListeners.
- Laissez la boîte à outils pour passer cet événement à AWTEventListeners.
- Si personne n'a consommé un événement clé, permettre au KeyboardFocusManager de les traiter.
- Autoriser les méthodes d'entrée pour traiter l'événement
- prétraiter les événements spéciaux avant la livraison
- Livrer événement pour un traitement normal
- Manipulateurs pour 4061116: Crochet pour navigateur pour les boîtes de dialogue modales à proximité:.)
- Permettre au pair pour traiter l'événement. Sauf KeyEvents, ils seront traités par les pairs après tous KeyEventPostProcessors (voir DefaultKeyboardFocusManager.dispatchKeyEvent ())
Maintenant, vous pouvez faire correspondre le flux ci-dessus avec votre description pour déterminer si son droit ou non. Mais le point est que vous devriez vraiment pas dépendre javadocs des cours privés, la raison étant que les développeurs de mettre à jour les soins habituellement les commentaires de Do not cours privés lorsque des changements de code, de sorte que les documents peuvent devenir obsolètes.