GUI de thread en Java (et SwingUtilities)
Je suis en train de faire un jeu simple en Java à l'aide de swing et je rencontre des problèmes avec mon GUI le gel de façon sporadique (en raison de problèmes de threading plus probablement) après l'appui sur un bouton qui est censé déclencher un interrupteur dans JPanels.
J'ai posté un sujet ici, qui a plus de détails sur le code, je suis en train d'utiliser (bien que j'ai fait la mise à jour du compte à rebours et obtenir que le travail d'amende). À partir des réponses à ce fil, il semble que l'aideSwingUtilities.invokeLater()
ou invokeAndWait()
pourrait être ce dont j'ai besoin pour résoudre le problème, mais je ne sais pas où dans mon code il est nécessaire ou exactement comment la mettre en œuvre.
Je ne connais pas bien le filetage et pourrait utiliser toute aide (de préférence un peu détaillée et avec des exemples de code) que je peux obtenir. Laissez-moi savoir si d'autres détails pourraient être utiles.
- Êtes-vous en faveur
Thread.sleep(...)
sur l'événement thread (HAE)? - non, pas plus. J'ai réécrit la partie du code qui a déjà été fait.
- Pouvez-vous partager votre code de mises à jour de la réponse à la composante?
- Avez-vous regarde le code que j'ai posté sur la page que j'ai relié à ma question? Qui a, fondamentalement, tout le code qui doit être pertinente à cette question.
- Si votre GUI se fige, vous pouvez obtenir un thread dump avec
jstack
(trouver l'ID de processus avecjps
), ou à partir de la sonsolectrl-break
(Windows) ouctrl-3
/ctrl-` (IIRC, Linux).
Vous devez vous connecter pour publier un commentaire.
Voir: Tutoriel: la Simultanéité dans le Swing
Généralement parlant, l'Event Dispatch Thread un thread unique, soufflant à travers les événements de la file d'attente, le traitement à la fois.
met un Exécutable sur cette file d'attente. Ainsi, il sera traité par l'EDT lorsque l'EDT finitions tout sur la file d'attente avant d' (C'est pourquoi dormir sur la file d'attente des blocs d'autres événements comme repeindre). Il est relativement rare d'appel invokeLater(..) de l'EDT lui-même, bien qu'il existe des situations où il est utile (généralement un hack). Je ne pense pas que j'ai eu un usage légitime des SwingUtilities.invokeAndWait(..) dans les 6 dernières années. Peut-être une fois.
javax.swing.Timer
peut être configuré de manière à feu qu'une seule fois ou périodiquement. Quand il se déclenche, il met un événement sur l'EDT de la file d'attente. Si vous avez des calculs intensifs de traitement qui doivent être faites, pensez à utiliserjavax.swing.SwingWorker
de faire le calcul sur un autre thread, et vous donner le résultat dans un thread-safe manière (ce qui est relativement rare).Un bon point à regarder est le docs. Dans votre cas, c'est ce qui explique comment
SwingUtilities.invokeLater()
travaille et où l'utiliser:Donc, dans vos actions qui modifie l'interface graphique, vous devez utiliser le
invokeLater
méthode permettant de s'assurer que le GUI l'habitude de congeler.Une autre bonne ressource est la Java des tutoriels. Ils couvrent la simultanéité dans le Swing.
Si vous avez certains travaux définis dans votre interface de code comme ceci
Et vous êtes en l'appelant, en l'attachant à un nouveau
Thread
Vous êtes l'exécution de votre travail dans le thread GUI, ce qui va causer des problèmes dans une application Swing.
Plutôt essayer ce (permettez-moi de mentionner, c'est juste un exemple d'utilisation)
Cela met votre
Runnable
travailleur à l'AWT File d'attente des Événements, et va l'exécuter lors de précédentes manifestations sont finis.MODIFIER: Voici l'exemple complet qui exécute le compte à rebours de 3 à 0 et puis tout ce que vous voulez faire après le compte à rebours.
TimerTask
s avecRunnable
s dans leur mise à jour et laJLabel
de numéro spécifique, et une autre fin de tâche qui s'arrête à laTimer
et fait ce que vous voulez faire après le compte à rebours est terminé. J'ai laissé de côté "commutation de panneau de jeu de la partie". Lire la principale méthode pour découvrir ce qu'il faut faire.J'ai créer un WorkerThread classe qui prennent soin de Threads et de l'interface de courant/thread principal . j'ai mis mon GUI application dans construct() la méthode de WorkerThread lorsqu'un événement de début d'incendie XXXServer ensuite, tous les threads sont activer et GUI de travail smoothlly sans gel. un coup d'oeil.
/**
* L'Action De L'Événement
*
* @see java.awt.de l'événement.ActionListener#actionPerformed(java.awt.de l'événement.ActionEvent)
*/
public void actionPerformed(ActionEvent ae) {
journal.info("actionPerformed commencer..." + ae.getActionCommand());