Comment utilisez-vous l'Event Dispatch Thread?
J'ai appris sur la façon de swing n'est pas thread-safe. Plonger plus profondément, j'ai découvert que chaque modification d'un composant swing doit être fait sur l'Event Dispatch Thread afin d'éviter divers problèmes associés avec le multithreading. Cependant, l'information semble complètement s'arrêter là. Il ne semble pas être un bon tutoriel qui explique comment le faire n'importe où accessibles sur internet.
Accumulant les informations de code affiché pour d'autres questions, il me semble que j'aurais à mettre en désordre, bloc de code autour de chaque swing simple modification dans mon programme (comme dans cet exemple tiré de ma propre code):
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
setTitle("Frame title");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setSize(800, 480);
setLocationRelativeTo(null);
setIconImage(Toolkit.getDefaultToolkit().createImage(ClassLoader.getSystemResource("Frame icon.png")));
}
});
} catch (Exception e) {
e.printStackTrace();
}
En gros, est-ce exact? Dois-je mettre ce code (ou l'équivalent avec invokeLater) autour de chaque modification apportée à un composant Swing dans mon code?
Aussi, pourquoi ne pas Balancer le faire automatiquement?
OriginalL'auteur Tharwen | 2011-10-25
Vous devez vous connecter pour publier un commentaire.
Le truc, c'est que lorsque swing vous appelle, il sera TOUJOURS dans l'EDT, de sorte que vous n'avez pas à vous inquiéter à ce sujet.
Toutefois, si vous êtes dans une minuterie ou d'une action déclenchée par un autre événement extérieur, votre thread principal ou tout autre sujet que vous avez créé, alors oui, vous devez utiliser invokeLater ou invokeAndWait.
En d'autres termes, oui balançoire ne faire "il" automatiquement. Avoir à utiliser invokeXx est tellement rare que si swing ont à faire à l'interne, il serait de perdre trop de temps.
De nombreux programmeurs java ne jamais comprendre cela, et il peut causer quelques jolies cochonnes dur-à-trouver des problèmes avec le dessin de votre interface graphique. Je ne souhaite swing a déclenché une exception lors de l'appel il pas à l'aide de l'EDT--Java aurait une meilleure réputation quand il est venu à des professionnels de l'Ihm si il l'a fait parce qu'il y aurait moins de la merde.
Microsoft windows 3.0/3.1 l'époque avait "Debug Binaires" qui permettrait de faire ce genre de vérification, de sorte que vous ne pas avoir à redémarrer à chaque fois que vous avez envoyé les mauvais arguments. Il m'énerve que Java n'avait pas le même, surtout depuis qu'il est assez intelligent pour être en mesure de compiler sur un commutateur de ligne de commande.
J'ai l'habitude de toujours mettre "dans" l'application Java, en remplacement de le repeindre gestionnaire(s) avec un CheckThreadViolationRepaintManager. Je m'en souviens très bien fonctionné : )
Maintenant que j'y pense ces jours-ci c'est probablement une chose facile à résoudre avec les aspects, mais d'un autre côté je ne suis pas tellement inquiet à propos de MOI, je suis inquiet à propos de tout le monde passe autour de rendre les gens pensent qu'il n'y a pas une telle chose comme une bonne ihm java. Une autre bonne façon serait de s'assurer que l'EDT thread jamais passe plus de .01 secondes, ou si dans votre code--plus et il doit lever une exception en vous de le mettre dans un thread de travail.
OriginalL'auteur Bill K
note que le code exécuté à partir de gestionnaires d'événement est déjà dans l'EDT (Cas de l'acronyme)
cela signifie que pour un usage général (alors que vous ne plaisante pas avec les swingworkers et threadpools et par exemple), vous êtes toujours à l'intérieur de l'EDT
et vous pouvez toujours interroger si vous êtes dans l'EDT avec
SwingUtilities.isEventDispatchThread()
noter également que dans votre code à l'appel à
invokeAndWait
échoue et renvoie une erreur lorsque vous êtes dans l'EDT déjàOriginalL'auteur ratchet freak
Fondamentalement, vous n'avez pas de dessiner ou de mise à jour de l'interface graphique à partir de l'extérieur de l'EDT.
Vous utilisez SwingUtilitis.invokeLater() à partir d'un autre thread pour assurer l'interface graphique de dessin ou de la mise à jour de code est exécuté sur le EDT.
par le code de dessin, il implique toutes les mises à jour des composants de l'interface utilisateur, donc oui, setSize() et setVisible() est une partie de la drawin code.
Voir stackoverflow.com/q/7196889/100836
Vous devez également créer de nouveaux threads pour faire une tâche coûteuse en dehors de l'EDT, sinon vous risquez de geler l'INTERFACE utilisateur.
OriginalL'auteur Zaki
Pas tous vos code de l'INTERFACE utilisateur doivent faire partie d'un exécutable dans un invokeLater appel. C'est tout simplement parce qu'une grande partie de votre programme sera exécuté sur l'EDT de toute façon. Vous avez besoin de distribuer les messages à l'EDT que lorsque vous êtes sur un thread différent.
OriginalL'auteur Savvas Dalkitsis