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 :

[MaJ] Thread et join() : le programme stoppe completement


Sujet :

EDT/SwingWorker Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Par défaut [MaJ] Thread et join() : le programme stoppe completement
    Titre original : [Thread] Thread, PopUp et EDT : je suis perdu

    Je commence à mélanger un peu tout et la fatigue aidant, j'abime plus mon code qu'autre chose. Je vais donc essayer d'expliquer le plus clairement possible mon problème qui je pense, est surtout un problème de conception.

    J'ai une frame principale dans laquelle j'affiche une JTreeTable.

    Quand la JTreeTable se construit, je fais des actions sur certains types de fichiers et ces actions prennent du temps. Je souhaite donc faire une barre de progression de type indéterminé (je ne connais pas le temps d'execution) qui apparait dans une fenetre type popup.
    Voici ce que j'ai compris que je devais faire par rapport aux thread/popup/edt : il faut que je mette les actions qui prennent du temps (celles sur les fichiers d'un type précis) dans un Thread. Pour ne pas avoir de problème d'affichage, il faut que je mette la fenetre PopUp dans l'edt en utilisant un Runnable et invokeLater. J'utilise le code suivant pour cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Runnable popUp = new Runnable() {
    		    public void run() { 
    		    	PopUpInfo fen = new PopUpInfo(); 
    //		    	fen.dispose();
    		    	}
    		};
    SwingUtilities.invokeLater(popUp);
     
    		Thread t = new Travail(path);
    		t.start();
    Travail execute l'action sur le fichier du type demandé.
    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
    class Travail extends Thread	{
        	private String path;
     
        	public Travail(String path)	{
        		this.path = path;
        	}
     
        	public void run()	{
        		int nombre = 1;
        		String ligne;
        		BufferedReader fichier;
     
        		try	{
        			fichier = new BufferedReader(new FileReader(path));
        			while ((ligne = fichier.readLine()) != null) {
            			if(ligne.startsWith("$$$$"))	nombrel++;
            	    }
        			listeIndex.add(nombre);
                	fichier.close();
        		}
        		catch(Exception err){System.out.println(" Exception Fichier "+ path);}
        	}
        }
    Au final, ce qu'il se passe, c'est que j'ai bien ma frame principale en fond et une fenetre popup par dessus. L'action de Travail est bien executé. MAIS l'affichage de la frame principale n'est pas fait (je dois fermer la popup et reduire puis afficher pour l'avoir). Alors, je sais que je n'ai pas insérer de moyen de fermer la popup une fois que j'ai terminé mon thread mais je ne crois pas que ce soit ça qui foute mon affichage par terre.

    Après, j'ai commencé à reflechir sur ce que je devais mettre dans le thread et je me demande si je ne dois pas y mettre egalement la jtreetable (en cherchant sur le forum, j'ai trouvé quelqu'un qui le faisait) ? Mais pour moi, la jtreetable, c'est de l'affichage donc ça doit être dans l'edt.
    Il y a aussi le invokeLater : je pensais que ça servait à modifier un element de l'affichage graphique à partir d'un thread mais au vu d'autres posts, ça n'a pas l'air d'être que ça.

    Enfin bref, je suis un peu perdu dans toutes ces notions et j'ai beau lire les faq et les différents posts, ça n'est pas clair dans ma tete et je n'arrive pas du coup à bien structurer mon code. Merci pour votre aide, j'en ai bien besoin

  2. #2
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bonjour,

    je n'ai pas bien saisi ton problème, mais je peux t'éclaircir les idées :
    - tout ce qui est manipulation graphique devrait être effectué par l'EDT.
    - tout ce qui est manipulation de données devrait être fait par un autre thread.

    Cependant on a quelques exceptions :
    - des fonctions comme setEnabled ou setBackground (manipulant des données) peuvent être appelées par l'EDT. Idem pour setText sur des petits textes (tant que le traitement est rapide).
    - des fonctions comme repaint (manipulant l'affichage) sont concues pour être appelées indifféremment par n'importe quel thread, ça finira par tomber sur l'EDT et le thread appelant ne fera pas grand chose.

    Généralement, tout ce qui risque de générer des évènements (AWTEvent) devrait être géré par l'EDT (redimensionnements, appel de focus, et même changement de hiérarchie des composants).

    Quand on est dans l'EDT (par exemple méthode actionPerformed) et qu'on veut lancer un taitement long sur des données, il faut lancer un nouveau thread.
    Quand on est dans un thread et qu'on veut faire quelque chose qui va générer des évènements, il faut le faire faire par l'EDT, avec la méthode SwingUtilities.invokeLater. Il y a aussi invokeNow, mais c'est un peu bourrin et ça peut ne rien résoudre ...
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Par défaut
    Bon, c'est bien ce que j'avais compris donc ça me rassure.
    Mais il y a quand meme quelque chose que je ne comprends pas :
    je lance la popup avec la barre de progression et ensuite, je lance un thread où je fais mon traitement long. Quand le thread se termine, il ferme ma popup. Jusque là ça passe bien mais l'appilication est comme figée : je dois la reduire dans la barre des taches puis la reafficher pour que ça continue. D'où est ce que ce problème peut venir ?

  4. #4
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Citation Envoyé par Zanton
    Quand le thread se termine, il ferme ma popup.
    Ca ne correspond pas vraiment au code que tu as donné, et ce dispose doit être appelé par l'EDT.

    Pourquoi ne fais tu pas quelque chose comme ça :
    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
    class Travail extends Thread	{
        	private String path;
        	private JDialog dialog;
     
        	public Travail(String path, Autres arguments pour la dialog)	{
        		this.path = path;
                    dialog = new ...;
        	}
     
        	public void run()	{
     
                    dialog.setVisible(true);
                    // ton travail
                    dialog.dispose();
     
        	}
        }
    A savoir que setVisible(true) et dispose() sont des méthodes sûres que l'on peut appeler de n'importe où. J'en suis presque certain.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Par défaut
    Merci pour ta réponse.

    Alors pour la fenetre qui se ferme, c'est parceque j'ai modifié le code entre temps pour que ça le fasse Mais je ne le fais pas comme toi. Je le ferme à la fin du run() en ayant mis la variable PopUpInfo2 fen en statique et en utilisant un invokeLater, toujours dans le run().
    Et du coup, je me pose une question par rapport à ton code : là, tu crées ta fenetre de dialogue dans le constructeur de Travail or cette classe derive d'un Thread donc elle ne va pas être dans l'EDT non ? Ou bien c'est seulement ce qui est dans run() qui est considéré comme étant dans le Thread (à la reflexion, je penche pour cette deuxième solution mais je veux bien confirmation )

    Edit : j'ai suivi le même schema de code que toi et ça ne change rien par rapport à mon problème précédent : la frame principale reste figée. Je dois la recharger ou quelque chose comme ça pour qu'elle soit actualiser et que le traitement continu ?

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Par défaut
    Bon, je pense que mon problème d'affichage est lié à autre chose : vu que le thread est effectué à part, le programme principal continue lui. Or ce dernier a besoin d'infos fournies par le thread donc il faut que le programme principal attende la fin du thread. Après recherche et expérimentation, il faut que j'utilise join() mais j'ai un problème : si je mets mon t.join() après mon t.start(), le programme se bloque (pas d'affichage de popup ou quoique ce soit). En debuggant avec Eclipse, je vois qu'il s'arrete dessus et ne fait plus rien après. J'ai donc mis un join(1000) pour voir ce que ça donne et là, ça me fait une sorte de wait() : au bout de 1s, le programme se poursuit (affichage du popup et calcul effectué) mais je me retrouve avec le meme problème d'affichage ce qui me parait logique vu que le join ne fait pas ce que je lui demande.

    Je mets le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Thread t = new Travail(path);
    		t.start();
     
    		try	{
    			System.out.println("La");
    			t.join(1000);
    			System.out.println("Puis la");
    		}
    		catch (InterruptedException err)	{
    			System.out.println("Problème lors de la fin du thread");
    		}
    Est ce que je m'y prends mal avec cette méthode (pourtant les exemples que j'ai trouvés sont assez explicites) ou j'ai raté quelque chose ?

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

Discussions similaires

  1. Réponses: 14
    Dernier message: 04/06/2007, 22h43
  2. [Threads Win32]join et queue
    Par NiamorH dans le forum Windows
    Réponses: 2
    Dernier message: 03/04/2007, 11h48
  3. Réponses: 2
    Dernier message: 06/03/2007, 11h07
  4. [Débutant] [Thread] Faire patienter un programme java....
    Par yoxx dans le forum Concurrence et multi-thread
    Réponses: 3
    Dernier message: 25/09/2005, 12h36
  5. [Thread] Blocage dans mon programme
    Par Xo Sonic oX dans le forum EDT/SwingWorker
    Réponses: 4
    Dernier message: 18/06/2005, 17h12

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