J'ai un programme Swing qui effectue une recherche en fonction du contenu de certains champs de texte et des paramètres d'une paire de boutons radio (dans un groupe de boutons). Le programme recherche automatiquement lorsque certains champs de texte perdent leur focus. Le problème survient lorsque l'événement de perte de focus est déclenché par un clic sur l'un des boutons radio. L'événement de focus perdu sur le champ de texte est traité avant que les valeurs du bouton radio isSelected() aient changé, donc la recherche est effectuée avec les mauvais paramètres (ie vieux), au lieu des paramètres basés sur le nouveau réglage de la radio boutons.Comment attendre que le bouton radio soit sélectionné en événement de focus perdu
J'ai essayé d'invoquer la recherche en utilisant ma propre méthode invokeWhenIdle (montrée ci-dessous) pour lancer la recherche après que la file d'attente d'événements se soit stabilisée, mais elle utilise toujours l'ancien réglage des boutons radio.
Ma seule solution de travail est de retarder pendant 250 millisecondes dans l'événement focus perdu avant d'exécuter la recherche, de sorte que les boutons radio ont le temps de changer. Cela fonctionne, mais cela rend l'interface utilisateur léthargique.
De meilleures idées?
public static void invokeWhenIdle(final int a_max_retry, final Runnable a_runnable) {
if (a_max_retry <= 0) {
throw new IllegalStateException("invokeWhenIdle: Could not run " + a_runnable);
}
// get the next event on the queue
EventQueue l_queue = Toolkit.getDefaultToolkit().getSystemEventQueue();
AWTEvent l_evt = l_queue.peekEvent();
if (l_evt == null) {
// nothing left on the queue (but us), we can do it
SwingUtilities.invokeLater(a_runnable);
} else {
// still something in the queue, try again
SwingUtilities.invokeLater(new Runnable() {
public void run() {
invokeWhenIdle(a_max_retry - 1, a_runnable);
}
});
}
}
Eh bien, il n'y a pas de véritable moyen de savoir quand vous devriez lancer la recherche ou quand vous devriez attendre parce que l'utilisateur peut cliquer sur un bouton radio.Vous devrez soit utiliser une minuterie pour lancer la recherche après un certain laps de temps depuis la dernière frappe de l'utilisateur, soit ne pas le faire et laisser l'utilisateur démarrer la recherche en cliquant sur le bouton «Rechercher». Vous ne devriez pas avoir besoin de jouer avec 'EventQueue' comme ceci - jetez un coup d'œil à [How to Use Swing Timers] (http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html). Lorsque vous détectez une frappe, redémarrez le minuteur –
Ma solution de contournement pour cela était de rendre les boutons radio non focalisables (setFocusable (false)) afin qu'ils ne provoquent pas l'événement de focus perdu sur les champs de texte. Toujours curieux s'il y a une solution dans l'autre sens. – Mitch
Vous n'avez pas besoin de faire cela non plus, vous pouvez utiliser une minuterie connectée aux frappes sur le champ de recherche. –