Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

EDT/SwingWorker Java Discussion :

Plusieurs Threads et InvokeLater


Sujet :

EDT/SwingWorker Java

  1. #1
    Futur Membre du Club
    Plusieurs Threads et InvokeLater
    Bonsoir à tous

    Je me permets de solliciter votre aide !

    Dans le code suivant :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    			final StatusDialog dg = StatusDialog.getStatusDialog(this,
    					"", false);
    			final Iterator<AbstractDataProvider> itr = todo.iterator();
    			AbstractDataProvider prov;
    			final RefBoolean finished = new RefBoolean();
    			while (itr.hasNext())
    			{
    				finished.setVal(false);
    				prov = itr.next();
    				dg.setTitle(prov.toString());
    				prov.execute(prov.toString(), source, target,
    						this.multithreadCheckBox.isSelected(),
    						this.logTextArea, new Runnable() {
     
    							@Override
    							public void run() {
    								finished.setVal(true);
    							}
    						}, dg);
    				while (!finished.getVal())
    					Thread.sleep(1000);
    				i = providerComboBox.getSelectedIndex();
    				this.providerComboBox.removeAll();
    				for (AbstractDataProvider provider : DataProviderFactory
    						.getProviders()) {
    					this.providerComboBox.addItem(provider);
    				}
    				providerComboBox.setSelectedIndex(i);
    			}
    			dg.dispose();


    ... on exécute chaque élément de la liste todo (cela se fait dans une autre partie du code) dans un nouveau thread. De plus, chacun de ces threads lance un ExecutorService qui lui même va lancer pleins de threads différents. On ne passe pas à l'élément suivant de la liste todo tant que l'ExecutorService n'a pas terminé la tâche. Et juste avant de passer à l'élément suivant de la liste todo le new Runnable que l'on voit ci-dessus est lancé dans le thread de l'élément en cours de la liste todo. (Vous suivez )

    De plus, la variable dg est une boîte de dialogue censée afficher la progression des ExecutorService (le pourcentage est mis à jour chaque fois qu'un Thread d'un ExecutorService se termine), et elle contient aussi un bouton mettant fin à l'ExecutorService.

    Le problème, c'est que toutes les tâches demandées s'effectuent correctement mais la boîte de dialogue reste désespérément vide jusqu'à ce que toutes les tâches aient été exécutées...

    Voici encore les deux fonctions de la classe StatusDialog permettant respectivement de mettre à jour la barre de progression et de mettre fin à l'ExecutorService en cours en cliquant sur le bouton :

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	public void setProgress(final int value) {
     
    		SwingUtilities.invokeLater(new Runnable() {
     
    			@Override
    			public void run() {
     
    				StatusDialog.this.pb.setValue(value);
    				StatusDialog.this.pb.invalidate();
    			}
    		});
    	}

    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public void listenExecutor(final ExecutorService pool)
    	{
    		cancel.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent arg0) {
    				canceled = true;
    				pool.shutdownNow();
    			}
    		});
    	}


    Quelqu'un aurait-il une solution à mon problème ? Merci d'avance

  2. #2
    Expert éminent sénior
    Ben comme toujours dans ces cas là, c'est parce que tu squatte le thread EDT et que donc aucun affichage ne peux se faire pendant ce temps là.
    Ce qui est amusant c'est que tu parle de swingWorker dans ton titre, mais tu n'en utilise pas. Hors en utiliser un aurais résolu ton problème
    David Delbecq Java developer chez HMS Industrial Networks AB. &#12288;&#12288;&#12288;LinkedIn | Google+

  3. #3
    Futur Membre du Club
    En fait je voulais dire SwingUtilities.InvokeLater et non SwingWorker. (J'ai corrigé le titre)

    Et justement je pensais que l'utilisation d'InvokeLater (que j'emploie dans la boîte de dialogue) devait justement éviter ce problème...

    Où mettrais-tu un SwingWorker ?

  4. #4
    Futur Membre du Club
    Bon finalement j'ai contourné le problème en créant une boîte de dialogue pour chaque élément de la liste todo plutôt que d'utiliser chaque fois la même. Cela me permet d'avoir un bouton d'annulation pour chaque tâche de la liste et de les lancer toutes en même temps. Ceci dit je n'ai pas vraiment compris où précisément ça coinçait.

  5. #5
    Expert éminent sénior
    invokeLater sert à lancer quelquechose sur l'EDT sans attendre son résultat. Cela n'empêche pas que ce quelquechose bloquera l'EDT. C'est destiné à pouvoir executé, depuis un autre thread, des instruction sur l'EDT car on ne manipule pas les composants graphiques en dehors de l'EDT en java.

    la différence entre invokeLater et invokeAndWait tient au fait que la dernière attends que l'opération (le quelquechose) soit terminé avant de retourner.

    Swingworker est destiné à travailler avec cela + un thread séparé pour les calculs long, et facilite le travail de mise à jour de l'interface depuis le thread de travail, via ses méthodes publish / process
    David Delbecq Java developer chez HMS Industrial Networks AB. &#12288;&#12288;&#12288;LinkedIn | Google+

  6. #6
    Futur Membre du Club
    OK merci pour ton explication ! ...et désolé de ne réagir que maintenant. J'y songerai la prochaine fois que je devrai travailler là-dessus

###raw>template_hook.ano_emploi###