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

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    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 émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    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 ...

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    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 émérite
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Points : 2 410
    Points
    2 410
    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.

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    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 du Club
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    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 ?

  7. #7
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,

    Que se passe-t-il dans le constrcuteur de PopUpInfo() ???
    Dans quel Thread tu fais le join() ???

    Il faut éviter à tout prix d'effecter des traitements long ou bloquant (comme join()) dans l'EDT, sinon cela te bloquera toutes ton interface !!!

    Pour effectuer des traitements long tu peux utiliser la classe SwingWorker qui sera intégrer dans Java 6. La version compatible avec Java 5.0 est disponible ici : https://swingworker.dev.java.net/

    Sinon il y a aussi une version moins évolué qui doit être compatible avec Java 1.2 : http://java.sun.com/docs/books/tutor...ingWorker.java

    Je te conseille également de lire ceci : How to use thread

    Et un tutoriel de Gfx sur le sujet va prochainement être publié, j'essayerais de repasser par là pour le signaler lorsque ce sera le cas...

    Maintenant pour en revenir à ton problème :
    • Que font chacun de tes threads (EDT compris) ?
    • Dans quel thread tu appelles le code que tu montres ?
    a++

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    Par défaut
    Merci pour tes questions précises.
    Citation Envoyé par adiGuba
    Salut,

    Que se passe-t-il dans le constrcuteur de PopUpInfo() ???
    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
    public PopUpInfo()	{
        	super("Progression de la tâche...");
        	progressBar = new JProgressBar();
        	progressBar.setIndeterminate(true);
        	progressBar.setStringPainted(true);
            progressBar.setString("");
     
            taskOutput = new JTextArea(50, 20);
            //taskOutput.setMargin(new Insets(5,5,5,5));
            taskOutput.setEditable(false);
     
            JPanel panel = new JPanel();
     
        	panel.add(progressBar);
            panel.setSize(200,50);
     
            this.add(panel, BorderLayout.PAGE_START);
            this.add(new JScrollPane(taskOutput), BorderLayout.CENTER);
     
        	this.getContentPane().add(panel);
     
        	this.setSize(400,100);
        }
    Le setVisible(true) n'est pas dedans car j'ai suivi le conseil donné plus haut, pas de différence. Le Jtextarea n'est pas utilisé, c'est pour plus tard.


    Dans quel Thread tu fais le join() ???


    Il faut éviter à tout prix d'effecter des traitements long ou bloquant (comme join()) dans l'EDT, sinon cela te bloquera toutes ton interface !!!
    Je le fais dans une classe liée à l'EDT. J'ai essayé dans le Thread qui fait mon calcul long et que je dois stopper mais je me retrouve avec le meme problème d'affichage.

    Pour effectuer des traitements long tu peux utiliser la classe SwingWorker qui sera intégrer dans Java 6. La version compatible avec Java 5.0 est disponible ici : https://swingworker.dev.java.net/

    Sinon il y a aussi une version moins évolué qui doit être compatible avec Java 1.2 : http://java.sun.com/docs/books/tutor...ingWorker.java

    Je te conseille également de lire ceci : How to use thread

    Et un tutoriel de Gfx sur le sujet va prochainement être publié, j'essayerais de repasser par là pour le signaler lorsque ce sera le cas...
    Je prends bonne note de toutes ces infos, je vais regarder SwingWorker en attendant ta reponse :p

    Maintenant pour en revenir à ton problème :
    • Que font chacun de tes threads (EDT compris) ?
    • Dans quel thread tu appelles le code que tu montres ?
    a++
    1- L'EDT affiche une frame avec deux JTable l'une en dessous de l'autre et une JTreeTable en dessous des deux JTable. Je fais appel à des calculs assez longs en fonction de l'extension des fichiers qui sont dans la JTreeTable. Ce sont ces calculs que j'ai finalement mis dans un Thread. Au final, ça ne fait que deux threads : l'EDT et celui pour les calculs longs.

    2- Le code que je montre dans mon dernier post est dans l'EDT.

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    Par défaut
    J'ai regardé la classe SwingWorker et je ne vois pas trop en quoi elle est utilie dans mon cas : mon problème ici est que je dois attendre la fin du thread pour continuer mon programme. Avec SwingWorker je peux le faire mais ça n'est pas vital puisque je ne compte pas mettre à jour d'éléments swing de mon EDT. Le seul Swing qui intervient, c'est la popup qui apparait pour dire que le travail est en cours de progression.

  10. #10
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    En fait il faut limité au maximum les "gros" traitement dans l'EDT.
    Ce dernier ne doit être utilisé que pour mettre à jours l'affichage.

    Pour rappel toutes les méthodes des listeners Swing sont exécuté dans l'EDT (actionPerformed(), mouseclicked(), etc.).



    La classe SwingWorker permet de simplifier la gestion des Threads.

    Explications (j'utilise le nom des méthodes de la classe SwingWorker pour Java 5.0/6, et entre parenthèse l'équivalent dans la précédente version) :

    Pour effectuer un traitement long dans une interface graphique, il faut hériter de SwingWorker et implémenter la méthode doInBackground() (construct()). Cette méthode doit contenir le traitement mais ne doit pas modifier l'interface graphique. Elle peut éventuellement retourner un résultat que tu pourras utiliser plus tard en le récupérant avec get() (getValue()). Enfin, lorsque le traitement est fini, la méthode done() (finished()) est appellé dans l'EDT, afin de mettre à jours l'affichage.


    Par exemple dans ton cas tu pourrais faire (le code en rouge est exécuté dans l'EDT, celui en bleu dans un autre thread) :
    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
        public void actionPerformed(ActionEvent e) {
           // On crée la fenêtre Popup et on l'affiche (on peut puisqu'on est dans l'EDT) : 
            final PopUpInfo popup = new PopUpInfo();
            popup.setvisible(true);
            
            // Creation du SwingWorker :
            SwingWorker<String,Object> worker = new SwingWorker<String,Object>() {
                @Override
                protected String doInBackground() throws Exception {
                     StringBuffer buffer = new StringBuffer();
    
                    // Code de lecture du fichier
                    ...
                    
                    return buffer.toString();
                }
                
              @Override
                protected void done() {
                    // Une fois que c'est terminé on ferme la popup :
                    popup.setVisible(false);
                    popup.dispose();
                }
            };
            
            // On démarre le traitement 
            worker.execute();
        }
    Donc dans ton traitement tu initialises la Popup et tu l'affiches, avant de créer le Swingworker et de l'exécuter avec execute() (start()). Ce dernier lancera la méthode doInBackground() dans un autre thread, et une fois terminé appellera la méthode done() dans l'EDT afin de fermer la popup... Ainsi ton EDT n'est pas occupé par le traitement long et il n'attend pas que le traitement soint fini. Ainsi tu n'as pas de bug d'affichage...

    La classe de Java 5.0/6 utilise les Generics. Le premier type correspond au type de l'objet retourné par doInBackground() et get(). Le second correspond au type passé aux méthode publish()/process().
    En effet la nouvelle version possède un couple de méthode publish()/process() qui permettent de faire passer des objets de la méthode doInBackground() (et donc du thread) vers l'EDT : Lorsque tu appelles publish() les paramètres seront passé à la méthode process() qui sera exécuté dans l'EDT. Cela permet d'effectuer des mises à jours de l'affichage pendant le traitement... (note toutefois : plusieurs appels successif à publish() peuvent aboutir à un seul appel à process() mais avec le cumul de tous les paramètres). Ces méthodes acceptent un nombre variable d'arguments...

    Si tu veux simuler cela avec la version pre-Java 5 tu devras utiliser des appels à invokeLater() dans la méthode exécuté dans ton thread...



    En prévisualisant j'ai vu que tu avait posté à nouveau :
    Citation Envoyé par Zanton
    J'ai regardé la classe SwingWorker et je ne vois pas trop en quoi elle est utilie dans mon cas : mon problème ici est que je dois attendre la fin du thread pour continuer mon programme.
    Pourquoi tu dois attendre la fin du traitement ? L'EDT ne dois jamais attendre un autre thread...

    a++

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    Par défaut
    Merci pour les précisions sur le SwingWorker.
    Pourquoi tu dois attendre la fin du traitement ? L'EDT ne dois jamais attendre un autre thread...
    J'ai donc une JTreeTable dans ma frame principale. Selon l'extension des fichiers qui apparaissent dedans, je veux pouvoir accomplir des actions. Par exemple, Je veux que quand la JTreeTable rencontre un fichier avec une certaine extension (.txt on va dire), elle execute la methode lireTxt(). C'est de cette methode dont on parle et qui demande une ouverture de popup et le thread qui pose problème.
    L'appli dans le thread fait un calcul (le nombre de lignes du fichier on va dire) et stocke cette valeur dans un ArrayList. Dans la JTreeTable, j'ai une colonne où je dois indiquer le nombre de lignes du fichier .txt et c'est pour ça que je dois attendre la fin du thread. Sinon la JTreeTable continue son affichage et demande des infos à l'ArrayList qui n'est pas encore remplie. Ca me sort donc une erreur qui bloque, je pense l'affichage.

    En gros, je fais mon traitement sur les fichiers au fur et à mesure de l'affichage de la JTreeTable. Si je ne stoppe pas ma JTreeTable, elle va demander des infos qu'elle n'a pas et c'est ce qui provoque le blocage de l'affichage amha.
    Selon toi, je devrais faire quoi ? Faire afficher toute la JTreeTable et ensuite faire mes opérations sur les fichiers (c'est plus complexe à cause de la structure de la JTreeTable) ?

  12. #12
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zanton
    Selon toi, je devrais faire quoi ? Faire afficher toute la JTreeTable et ensuite faire mes opérations sur les fichiers (c'est plus complexe à cause de la structure de la JTreeTable) ?
    Ton composant JTreeTable n'a pas à aller récupérer les données... Ce n'est pas le rôle d'un composant. si tu bloques l'EDT c'est normal que ton interface graphique soit gelé...

    Je ne sais pas d'où sort ce composant JTreeTable, mais il devrait avoir un modèle qui permettent de renseigner les valeurs qu'il contient. C'est sur ce modèle que tu dois intervenir.
    1. Tu affiches ton JTreeTable avec un modèle vide (ou partiellement vide).
    2. Tu lances ta tâche de fond en laissant l'EDT continuer son travail.
    3. Dans ta tâche de fond, dès que tu as une donnée à afficher, tu "l'envoies" au modèle pour qu'il mette à jours l'affichage (généralement cela doit être fait dans l'EDT, donc soit via invokeLater() soit via les méthodes publish()/process()).
    Ainsi ton composant est mis à jours au fur et a mesure que ta tâche de fond récupère les infos...

    a++

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    Par défaut
    Ma JTreeTable a effectivement un Model et je bosse dessus (je pensais que tu savais comment ça fonctionnait en fait : http://java.sun.com/products/jfc/tsc...le2/index.html pour infos). Toutes les opérations que je décris sont fait dans une classe FileSystemModel2.

  14. #14
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zanton
    Ma JTreeTable a effectivement un Model et je bosse dessus (je pensais que tu savais comment ça fonctionnait en fait : http://java.sun.com/products/jfc/tsc...le2/index.html pour infos).
    Non je ne l'ai jamais utilisé...

    Donc au lieu de bloquer l'EDT tu dois utiliser invokeLater pour mettre à jour le modèle, ce qui mettra à jours l'affichage (puisque l'EDT ne sera pas bloqué)

    a++

  15. #15
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Pour plus de détail sur l'EDT et les Threads avec Swing :

    Tutoriel : Threads et performance avec Swing par Romain Guy
    a++

  16. #16
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Points : 722
    Points
    722
    Par défaut
    Pour ce qui est de la JTreeTable, il faut que tu modifies ta classe FileNode (ou équivalente) pour qu'elle stocke toutes les infos que tu souhaites afficher => tu rajoutes des varaibles membres.
    Ensuite, tu modifies ta méthode getValueAt() de manière à ce qu'elle appelle les accesseurs adéquats.
    Ainsi, tu vas gagner beaucoup en temps d'affichage.

    Au départ, je ne stockais pas toutes mes infos dans des varaibles membre et je les recalculais à chaque fois, ce qui faisait que l'affichage, le rafraîchissement et le défilement étaient très longs. Depuis que j'ai fait ça, j'ai divisé mes temps d'affichage par 10! (minimum)

    Si t'as besoin d'autres infos sur ce composant, n'hésite pas.

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    Par défaut
    Merci pour toute ton aide seiryujay
    Sur ce point là, je crois qu'on en a déjà parlé d'ailleurs, c'est un peu différent car j'ai un traitement long et si je le fais dans la classe FileNode et que je l'appelle avec getValueAt(), je vais bloquer l'affichage car je serai dans l'EDT pour faire mon long calcul. Effectivement, si je faisais mes calculs directement dans le getValueAt() ça poserait problème de les refaire à chaque fois mais le souci est ailleurs cette fois ci. A moins que je n'ai zappé un truc.

  18. #18
    Membre éclairé
    Avatar de seiryujay
    Profil pro
    Inscrit en
    Mars 2004
    Messages
    950
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2004
    Messages : 950
    Points : 722
    Points
    722
    Par défaut
    Citation Envoyé par Zanton
    Merci pour toute ton aide seiryujay
    Sur ce point là, je crois qu'on en a déjà parlé d'ailleurs, c'est un peu différent car j'ai un traitement long et si je le fais dans la classe FileNode et que je l'appelle avec getValueAt(), je vais bloquer l'affichage car je serai dans l'EDT pour faire mon long calcul.
    Justement, tu dois faire ton long calcul une seule fois, à l'initialisation de ta JTreeTable, et stocker les données dont tu as besoin dans des variables membres, et ne faire qu'appeler des accesseurs dans getValueAt(), et non pas ton traitement long...

    Mais c'est peut-être moi qui rate quelque chose.

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

    Informations forums :
    Inscription : Mars 2006
    Messages : 117
    Points : 64
    Points
    64
    Par défaut
    Je ne peux pas faire mon calcul long à l'initialisation de la JTreeTable puisque c'est en fonction de ce qu'elle "trouve" (type de fichier) que je fais mes calculs.

  20. #20
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par Zanton
    Je ne peux pas faire mon calcul long à l'initialisation de la JTreeTable puisque c'est en fonction de ce qu'elle "trouve" (type de fichier) que je fais mes calculs.
    C'est pour cela que je te conseillais d'utiliser SwingWorker :
    • Tu effectues tes traitements long dans la méthode doInBackground(), et tu met à jours l'affichage pendant le traitement via process() et/ou à la fin avec done()
    a++

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

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