8
votes

appeler invokeandwait de l'EDT


15 commentaires

Avez-vous un repeindre () appeler n'importe où (comme dans gui.update () )?


Valider est complètement différent de repeindre .


J'ai ajouté dans un repeindre mais cela n'avait aucun effet.


Je ne peux pas voir votre image (pare-feu). Quelle est la profondeur de la pile? Y a-t-il une possibilité d'obtenir une version texte?


D'accord merci. Cela semble être une liste de threads de fonctionnement plutôt que de la pile. Néanmoins, de ce que je peux voir là-bas, il n'y a pas de problème évident (pas de discussions inhabituelles). Pouvez-vous cliquer avec le bouton droit de la souris sur le fil eventeue et la suspendre, puis dites-moi quelle est la méthode utilisée par l'utilisateur le plus proche du sommet?


C'est HumanPlayer.ACT à la ligne qui lit exécuté.wait () (dans le code ci-dessus)


Ah, il y a votre problème alors. Vous appelez attendre () dans une boucle, mais il n'y a pas d'autre fil qui peut mettre à jour tout ce que hasperformedaction () vérifie. Vous devrez repenser ce morceau de la conception.


Merci beaucoup, je vais devoir rester assis et penser très dur maintenant


Désolé une autre question. Cela signifie-t-il que l'interface graphique ne retira que après que cette méthode revienne? parce que j'en ai besoin pour repeindre un ensemble de choix pour l'utilisateur, puis attendez que l'utilisateur effectue une action et renvoie cette action


Oui, l'interface graphique repeint sur l'événement eventeue, donc si vous travaillez sur elle (comme vous êtes là), alors il ne peut pas repeindre avant d'être fait. Vous devrez peut-être aller à un design modal (l'interface graphique fait différentes choses en fonction de quel mode il est dans).


Puis-je ne pas décharger l'attente d'un autre fil (à l'aide de SwingWorker) de sorte que la file d'attente d'événement devienne libre et peut repeindre?


Oui ... mais vous ne pouvez pas obtenir de saisie de votre interface graphique pendant que vous utilisez l'événementEUEUE et que vous ne pouvez pas (ou au moins, je ne dois pas) accéder à votre interface graphique d'un fil différent. Soyez très prudent ici.


Ahh qui pose un problème parce que j'ai besoin d'une entrée de l'utilisateur via l'interface graphique, Hmm ... Cela s'est avéré être plus de travail que ce que j'ai négocié pour


Comme je l'ai dit, une conception modale pourrait être votre meilleur pari.


Merci encore pour votre aide, très apprécié


5 Réponses :


5
votes

invokeandwait () est destiné à être appelé à partir du fil non-gui. Il envoie un objet d'objet exécutable sur le fil de l'interface graphique où il sera exécuté.

Il ne reste plus de point dans l'envoi d'un objet annoncable à partir du thread de l'interface graphique. Il a le même effet que Calling exécuté () sur l'objet directement (code> directement.


3 commentaires

Oui, y a-t-il une autre façon d'exécuter cette commande et d'attendre l'achèvement avant que le reste de la méthode soit exécuté?


Je pense que c'est déjà comment cela fonctionne - le thread de l'événement est un seul thread afin de compléter l'appel GUI.UPDATE avant de continuer.


Ce que je n'avais pas compris, c'est que le fil ne signifie pas du tout la méthode / la classe, du tout. Tout ce problème dépend de l'endroit où la chaîne des appels de méthode était a commencé .



1
votes

basé sur les commentaires, il semble que vous ne retiriez pas le cadre une fois que les actions sont terminées. Si vous ne le faites pas, l'écran ne sera mis à jour que sur ce qui semble être des temps aléatoires (lorsqu'une autre fenêtre se déplace à l'avant, peut-être).

Intérieur Gui.update , je vous suggère de faire le Dernière ligne: xxx

(plus ou moins, selon vos circonstances).


EDIT: s'avère, le problème réel est cette boucle: xxx

car il n'y a qu'un seul thread d'application (qui se trouve être l'EDT), le résultat de hasperformedAction () ne peut jamais changer (en supposant que c'est un simple getter). Il n'y a pas d'autre thread pour changer la valeur. Comme cette boucle infinie est sur l'EDT, l'interface graphique ne peut jamais être repeinte; il se verrouille.


4 commentaires

J'ai essayé cela sans chance, l'interface graphique ne peint même pas initialement; L'écran reste blanc et le X dans le coin supérieur droit ne tue pas le processus


@Aly: Avez-vous déjà eu quelque chose à peindre à l'écran de ce projet (puis changé les choses plus tard)?


Oui, j'ai précédemment créé un nouveau gameinitializer à partir d'un autre fil (pas d'Edt) et l'interface graphique fonctionnait bien. Mais maintenant j'ai essayé de faire un autre jframe qui crée le gameinitializer qui brise maintenant les choses comme précédemment appelant invokeantwait allait bien (comme le fil initial n'était pas Edt)


@Aly: Pouvez-vous l'exécuter dans un débogueur et le casser pendant que l'écran est blanc? Les piles de chaque thread pourraient s'avérer intéressantes.



10
votes

La réponse était au lieu de faire appel à l'appel xxx pré>

à partir de l'EDT, faites-le exécuter sur un nouveau thread (non EDT) de sorte que plus tard lorsque invokeandwait code> est Appelé, il fonctionne correctement que le fil exécutant cette commande n'est pas l'EDT. Le code modifié est le suivant: P>

Thread t = new Thread(new Runnable() {
    @Override
    public void run() {
       new GameInitializer(userName, player, Constants.BLIND_STRUCTURE_FILES.get(blindStructure), handState);       
    }

   });
t.start();


0 commentaires

3
votes

Vous pouvez vérifier auparavant si votre thread d'appel actuel est déjà le répartiteur de l'événement: xxx

Notez que oscillabilité.invokeandewait (Runnable) Il suffit de déléguer au EventQuue .


0 commentaires

0
votes

Lorsque vous utilisez la bibliothèque Xchart Java, vous pouvez afficher votre tableau sur le bouton Cliquez avec ce code:

JButton btn = new JButton("View chart");
        btn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Thread t = new Thread(new Runnable() {
                    @Override
                    public void run() {
                        new SwingWrapper(yourChart).displayChart();
                    }
                });
                t.start();
            }
        });


0 commentaires