web-dev-qa-db-fra.com

java.awt.EventQueue.invokeLater expliqué

Je suis très curieux de savoir pourquoi devons-nous utiliser Java.awt.EventQueue.invokeLater pour contrôler les composants oscillants.

Pourquoi ne pouvons-nous pas faire cela dans un fil normal? Que se passe-t-il exactement dans les coulisses? D'après ce que j'ai remarqué si j'ai un JFrame je peux définir la visibilité sur vrai ou faux du thread principal sans obtenir d'erreurs, et cela semble fonctionner. Alors, qu'est-ce que j'obtiens exactement en utilisant Java.awt.EventQueue.invokeLater? Je suis également pleinement conscient que je peux utiliser SwingUtilities.invokeLater mais comme expliqué ici , ils semblent être une seule et même chose.

Merci à tous pour leur explication. J'espère que c'est une question valable.

EDIT: pour répondre à la question wumpz Nous pouvons créer un jframe

JFrame frame = new JFrame("Hello world");
frame.setSize(new Dimension(300, 300));
frame.setPreferredSize(new Dimension(300, 300));
frame.setMaximumSize(new Dimension(300, 300));
frame.setMinimumSize(new Dimension(300, 300));
frame.setVisible(true);
frame.pack();
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

Et sur le même fil, il a été créé, procédez comme suit.

for (int i = 0; i < 34; i++)
{
    System.out.println("Main thread setting to "+(!frame.isVisible()));
    frame.setVisible(!frame.isVisible());
}

Et rien à redire.

33
Quillion

Le traitement Swing complet est effectué dans un thread appelé EDT (Event Dispatching Thread). Par conséquent, vous bloqueriez l'interface graphique si vous calculiez des calculs de longue durée dans ce fil.

La façon d'aller ici consiste à traiter votre calcul dans un thread différent, afin que votre interface graphique reste réactive. À la fin, vous souhaitez mettre à jour votre interface graphique, qui doit être effectuée dans l'EDT. À présent EventQueue.invokeLater entre en jeu. Il publie un événement (votre Runnable) à la fin de la liste des événements Swings et est traité après le traitement de tous les événements GUI précédents.

L'utilisation de EventQueue.invokeAndWait est possible ici. La différence est que votre thread de calcul bloque jusqu'à ce que votre interface graphique soit mise à jour. Il est donc évident que cela ne doit pas être utilisé à partir de l'EDT.

Soyez prudent pas pour mettre à jour votre interface graphique Swing à partir d'un thread différent. Dans la plupart des cas, cela génère d'étranges problèmes de mise à jour/rafraîchissement.

Il y a toujours Java code là-bas qui démarre un JFrame simple à partir du thread principal. Cela pourrait causer des problèmes, mais n'est pas empêché par Swing. La plupart des IDE modernes créent maintenant quelque chose comme ça pour démarrer l'interface graphique) :

public static void main(String args[]) {
    Java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            new NewJFrame().setVisible(true);
        }
    });
}
41
wumpz

Tous plates-formes prises en charge offrent des bibliothèques graphiques à un seul thread. Le swing est multiplateforme. Par conséquent, les objets Swing GUI doivent être construits et manipulés uniquement sur le thread de distribution d'événement .

En passant, SwingUtilities.invokeLater() est une couverture pour EventQueue.invokeLater() depuis la version 1.3.

11
trashgod