IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
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 :

Bouton pour sortir d'une boucle


Sujet :

EDT/SwingWorker Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2014
    Messages : 9
    Points : 9
    Points
    9
    Par défaut Bouton pour sortir d'une boucle
    Bonsoir à tous (c'est mon premier post)

    Je me résigne à demander de l'aide car je n'arrive pas à résoudre le problème suivant. Dans le code :

    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
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    	private boolean doTask(final LinkedHashMap<String, Long> map,
    			boolean multithreaded, final boolean firstPass, final int count, StatusDialog dg) {
    		Logger.log("Running instance for: " + this.toString());
    		final AtomicInteger processed = new AtomicInteger();
     
    		ExecutorService pool;
    		if (multithreaded) {
    			Logger.log("Multithread execution");
    			pool = Executors.newCachedThreadPool();
    		} else {
    			Logger.log("Singlethread execution");
    			pool = Executors.newSingleThreadExecutor();
    		}
    		dg.listenMap(map);
    		for (final String key : map.keySet()) {
    			if (firstPass || map.get(key) == 0 || map.get(key) == -1)
    			{
    				pool.execute(new Runnable() {
    					@Override
    					public void run() {
    						long val = Database.this.doQuery(key);
    						Logger.log(key + " " + val);
    						map.put(key, val);
     
    						Database.this.reportProgress(100
    								* processed.incrementAndGet() / count);
    					}
    				});
    			}
    		}
    		try {
    			// all submitted tasks will be executed. wait for the pool to
    			// shutdown
    			pool.shutdown();
    			// returns true on success, false on timeout
    			return pool.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
    		} catch (InterruptedException e) {
    			Logger.log("Task execution failed. Not all queries completed");
    			return false;
    		}
    	}
    ... la boîte de dialogue de type StatusDialog nommée dg contient une barre de progression qui indique l'avancement du contenu de la boucle for. J'y ai ajouté un bouton Annuler, et je souhaiterais qu'un clic sur celui-ci arrête la boucle for du code ci-dessus et par conséquent que celle-ci cesse de lancer des nouveaux Runnable.

    Ne sachant pas trop comment procéder, j'ai essayé de procéder de la façon suivante. Dans la classe de la StatusDialog, j'ai rajouté la fonction suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	public void listenMap(final LinkedHashMap<String, Long> map)
    	{
    		cancel.addActionListener(new ActionListener() {
    			public void actionPerformed(ActionEvent arg0) {
    				map.clear();
    //				StatusDialog.this.dispose();
    			}
    		});
    	}
    ...où cancel est le bouton Annuler. J'appelle cette fonction avant la boucle for à l'aide de , dans l'espoir qu'un clic sur le bouton vide la map et ainsi que la boucle for, n'ayant plus rien à se mettre sous la dent, soit forcée de s'arrêter.

    Mais, évidemment puisque je demande de l'aide, cela ne marche pas.

    Comment faire pour que la boucle for s'arrête et cesse de lancer des nouveaux Runnable ?

    Merci d'avance pour vous éventuelles réponses

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Euh... Au moment où tu cliques sur le bouton, la boucle est terminée depuis longtemps, non pas parce qu'elle s'est arrêtée de boucler, mais parce qu'elle a terminé toutes ses itérations et que le programme a continué sur la suite.
    Quand tu appelles ExecutorService.execute() ça n'attend pas que l'exécution soit terminée, c'est d'ailleurs un peu pour ça que tu as pris un ExecutorService au lieu de juste faire ce que tu voulais faire à cet endroit.
    Donc la boucle est terminée, toutes les tâches ont été soumises à l'ExecutorService, et si tu veux qu'il annule les tâches en cours qu'il a, c'est à lui qu'il faut s'intéresser, pas à la boucle.

    Mais je pense que ce n'est pas bien programmé.
    C'est logique de vouloir faire les travaux longs dans un thread séparé, mais pas avec un ExecutorService, et surtout pas chaque action envoyée séparément. Il ne faut pas faire une boucle qui envoie des travaux à d'autre threads, il faut envoyer la boucle à un autre Thread. D'où l'inutilité d'un ExecutorService.
    Et pour gérer l'affichage de progression et un système d'annulation, il vaut mieux un SwingWorker qu'un simple Thread.

    Je ne sais toutefois pas bien faire de code GUI en Java, alors je déplace en section adaptée pour que tu aies de meilleures réponses.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    +1 pour l'utilisation d'un swingWorker plutôt qu'un ExecutorService qui n'a pas ce genre de but.

    Cependant, si tu as vraiment besoin de passer par l'executor service, l'arrêt se fait simplement en appelant

    qui attendra que la tâche en cours dans le service s'arrête (ou les tâches si le service a plusieurs threads) et refusera aux suivantes le démarrage.

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Septembre 2014
    Messages
    9
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Suisse

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Septembre 2014
    Messages : 9
    Points : 9
    Points
    9
    Par défaut
    OK, merci à vous pour vos explications. Je n'avait effectivement pas saisi que la boucle était terminée alors que l'ExecutorService tournait encore. Effectivement, il fallait simplement agir au niveau de l'ExecutorService et non au niveau de la boucle, ce qui est aussi plus simple à mettre en oeuvre. Et le shutDownNow() résout le problème.

    Après il s'agit d'un code que j'ai repris alors que la personne qui l'a créé n'est pas atteignable donc je ne connais pas le pourquoi du comment des subtilités. Je vais voir pour le SwingWorker.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2013] problème pour sortir d'une boucle
    Par toto159 dans le forum VBA Access
    Réponses: 16
    Dernier message: 30/10/2014, 12h14
  2. Réponses: 2
    Dernier message: 23/03/2013, 00h42
  3. sortir d'une boucle et reprendre pour la ligne suivante
    Par gueridonbis dans le forum PL/SQL
    Réponses: 4
    Dernier message: 21/07/2009, 22h06
  4. Probleme pour sortir d'une boucle while
    Par aikinhdo dans le forum Langage
    Réponses: 0
    Dernier message: 27/07/2007, 15h01
  5. bouton pour afficher/cacher une toolbar ??
    Par pi05 dans le forum MFC
    Réponses: 3
    Dernier message: 07/02/2005, 22h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo