8
votes

Méthode SetVisible dans Java Swing Hangs System

J'ai la demande d'interface graphique bancaire que je travaille actuellement et qu'il semble y avoir un problème avec la méthode SetVisible pour mon JDialog. Une fois que l'utilisateur a retiré un montant valide, je publie une simple boîte de dialogue indiquant la "transaction en cours". Dans ma méthode Dobackground, je continue à interroger pour vérifier si la transaction a été reçue. J'ai essayé d'utiliser Swingworker et je ne comprends pas pourquoi ça ne marche pas. Si je supprimais l'appel SetVisible, cela fonctionne bien, alors pourquoi SETVisible provoque-t-elle le suspendre? Voici le code qui est à l'intérieur de My Jbutton Mouselistener: XXX


1 commentaires

Quelle version de Java avez-vous vu ce blocage? Nous avons progressé de Java 6 à Java 8 et nous risquons de courir dans ce comportement.


4 Réponses :


6
votes

Vous affichez une boîte de dialogue modale afin que le code d'arrière-plan ne puisse pas exécuter que la boîte de dialogue soit fermée.

Ajouter une instruction System.T.PrintLN (...) après la SETVisible et vous le verrez, il n'exécute jamais.


0 commentaires

0
votes

CamickR vous donne une réponse correcte. Je veux ajouter que vous ne peut pas Modifier l'interface utilisateur en dehors de l'intervalle de l'événement (comme vous le faites dans #doinbackground ), Swing est uniforme Ainsi, violer cette règle pourrait conduire à des bugs très délicats et de choses étranges dans votre interface utilisateur.


0 commentaires

2
votes

SETVISIBLE est une méthode qui affecte l'interface graphique, ce qui provoque le démontre de quelque chose (et, dans le cas d'une boîte de dialogue modale comme la vôtre, jusqu'à ce que la boîte de dialogue soit fermée). Il (comme tout ce qui modifie l'interface utilisateur visible) devrait jamais être appelé sauf sur le fil d'expédition de l'événement Swing. Vous l'appelez à partir du DOINBackground méthode de SwingWorker , qui fonctionne sur un fil d'arrière-plan.

Ce que vous devez faire pour résoudre ce problème est de faire le waitforClose boîte de dialogue A variable Variable que vous créez avant d'appeler exécuter sur le swingworker puis appelle SETVisible sur immédiatement après démarrer le travailleur. xxx

Vous devez le faire dans cet ordre car sinon la boîte de dialogue modale vous empêchera de démarrer le travailleur.


0 commentaires

15
votes

Premièrement, il est recommandé de faire toutes les mises à jour de l'interface graphique dans le thread d'expédition d'événement Swing, c'est-à-dire à l'aide de la classe Swingutilites .

second, votre jdialog est Modal et donc bloque le thread dans lequel la méthode SETVisible (true) est appelée (dans votre cas, le fil principal, dans le cas suivant, le filetage de l'événement de balançoire).

Je ne dis pas que le code suivant est parfait, mais il devrait vous mettre sur la piste ... xxx

espère que cela aide.


5 commentaires

Merci pour les réponses rapides! Je suis toujours un peu fragile sur ce genre d'aspects de la programmation de l'interface graphique, mais je l'obtiens pour la plupart maintenant ...


Compréhension de la manière dont le fil d'événement swing-expédition fonctionne et comment l'utiliser de bonne manière était la partie la plus difficile de l'interface graphique swing pour moi. Prenez votre temps et faites-le bien, cela vous évitera beaucoup de problèmes plus tard.


La méthode terminée est exécutée sur le thread d'expédition de l'événement, donc je ne pense pas que vous devez utiliser des oscillabilités.Invokelater dans cette méthode. Voir docs.oracle.com / Javase / 6 / Docs / API / Javax / Swing / ...


De plus, cette réponse a une condition de course: il est possible que la méthode terminée soit appelée et la boîte de dialogue détruite avant que la boîte de dialogue soit définie sur Visible.


Il me manque peut-être quelque chose, je me concentrais principalement uniquement sur le problème de l'OP, mais de mon point de vue de la condition de course, vous mentionnez, n'est pas possible ici. Vous définissez la boîte de dialogue visible via le code ici avant d'appeler la méthode effectuée () . La raison en est que les deux actions sont effectuées de manière sérieuse dans le fil de l'événement Swing-Dispatch. L'utilisation du oscillabilité.invokelater (runnable) Methode publie les actions sur le thread de manière synchronisée, c'est-à-dire pas de condition de course que vous avez décrite est possible ici.