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

AWT/Swing Java Discussion :

2 problèmes : Thread & GridBagLayout


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France, Yvelines (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 61
    Par défaut 2 problèmes : Thread & GridBagLayout
    Bonjour,

    J'ai déjà été aidé sur ces forums et cela m'a permis de bien avancer mon application. Je travaille plus sur la forme ces temps-ci et cela me posent plusieurs problèmes.

    Je travaille sur une application qui permet de gérer des fichiers zip. J'ai une liste de fichier (dans une JList) et lorsque je double-clique sur un fichier zip, cela le décompresse et entre dans le dossier correspondant.

    J'ai opté pour le modèle MVC.

    1er problème : Thread [Résolu]
    Le décompressage d'un grop fichier zip peut prendre pas mal de temps. J'aimerais pour cela rajouter une petite fenêtre d'attente, simple, qui affiche juste un label avec apparition d'un petit point toutes les secondes et qui se réinitialise au troisième. Cependant c'est resté un échec, car les threads avec Swing sont plus compliqués que je ne le croyais, surtout concernant le rafraichissement des fenêtres.

    Les classes:
    VueApplication (hérite de JFrame) qui contient l'ensemble de mes boutons et la JList.

    ControleurListeFichier qui implémente MouseListener et qui lorsqu'on double clique sur un fichier, lance le décompréssage. Je n'ai pas le code avec moi, mais il ressemble plus ou moins à ç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
    18
    19
    20
    21
    public void action()
    {
    	MFile file = new MFile(modele.getCurrentPath + File.separator + list.getSelectedValue().toString());
     
    	if(file.isZip())
    	{
    		String nomDossier;	// nom du dossier décompressé
     
    		/* On lance la fenêtre d'attente. Ici j'ai essayé plusieurs méthodes [1] */
     
    		try {
    			nomDossier = FolderManager.compresser(file);
    		}
    		catch(Exception e) {System.out.println(e);}
     
                    // arret de la fenêtre [2]		
     
    		/* Suite du traitement, mise à jour de VueApplication */
    	}
    	vue.miseAJour(); // mise à jour de VueApplication, on est entré dans le dossier zip décompressé.
    }
    La méthode action est appelé lors d'un double-clique.
    MFile est une classe dérivé de File.

    FolderManager qui contient la méthode décompressage. Je n'ai pas le code avec moi la, je vous donne la structure :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static String decompressage(MFile file) throws Exception
    {
    	// Exécution d'une commande exec qui appelle le programme externe 7zip.
     
    	// Récupération des flux de sortie qui permettent de récupérer le nom du dossier résultant du décompressage
     
    	// Récupération des flux d'erreur.
     
    	// Attente avec process.waitFor() que le décompressage soit terminée.
     
    	return nomDossier;
    }
    J'ai aussi une classe VueAttente qui hérite de JFrame qui est la fenêtre d'attente, ayant un simple JLabel.
    Elle a pour méthodes :

    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
    public void action()
    {
    	while(running)
    	{
    		try{
    			Thread.sleep(1000);
    		}catch(...){}
     
    		setLabel("."); // rajoute un point au label à mettre à jour;
    	}
    }
     
    public void arret()
    {
    	running = false;
    }
    La méthode arret() est placé en [2].

    J'ai essayé plusieurs méthodes. Toutes ont fini avec le même résultat, création d'une fenêtre (vide ?!) avec mise à jour de celle-ci uniquement à la fin du décompressage.
    - J'ai au départ juste instancié la fenetre VueAttente en [1], me disant que de toutes les manières, une JFrame était toujours lancée dans un nouveau thread.
    - J'ai créé une classe ThreadAttente héritant de Thread que je lançais en [1] et qui elle lançait VueAttente dans un thread.
    - J'ai créé un thread dynamiquement en [1] dans lequel je lançais la méthode action() de VueAttente.
    - J'ai lancé le thread dans la méthode action() de VueAttente.

    Voila, je ne sais plus trop quoi faire. J'ai vu sur ces forums d'autres topics parlant du même problème, mais cela ne m'a pas apporté de réponse. Enfin, j'ai parcourus vos facs concernant les thread, notamment celle avec les méthodes InvokeLater, j'ai essayé mais ça n'a pas changé mes résultats.

    Je serais ravi si vous m'aidiez à résoudre ce problème, c'est celui qui m'insupporte le plus actuellement.

    2e problème : GridBagLayout
    Je me suis mis récemment à ce Layout Manager et je suis content d'en avoir compris le principe, cependant quelque chose me gène.
    J'ai un GirdBagLayout disposé de la manière suivante :

    [00] [10 20]
    [01] [11] [21]
    [02 12] [22]
    [03 13 23]

    Danc chacun de ces rectangles, j'ai un label. Cependant, lorsqu'un des labels est trop grand, au lieu de mettre des petits points à la fin de celui ci comme dans un GridLayout, et bien il continue à s'étendre. Ce qui fait que souvent par exemple, le label du rectangle [10 20] vient manger celui du [00]. Donc je préfèrerais avec les trois petits points.

    Comment empècher ces dépassements sans empècher les redimensionnements (lorsque j'agrandis ou rétrécis la fenêtre) ?

    (Faire à la place un GridLayout de 4 lignes contenant un BorderLayout, un GridLayout, un BorderLayout et un FlowLayout n'est pas plus efficace car les BorderLayout ne vont pas respecter la taille de mes cases à moins que je ne donne une taille fixe).


    3e Problème (BONUS )
    Vous n'êtes pas obligé de m'aider sur celui-ci car je n'y ai pas encore réfléchi.
    Lorsque je fais un drag and drop de fichier dans ma JList, j'aimerais lorsque je dois atteindre un dossier plus haut dans la ma liste, que la ScrollBare me fasse monter si je pointe le fichier vers le haut de la liste (pareil pour lorsque je dois descendre). Un indice éventuellement ?

  2. #2
    Expert éminent
    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
    Billets dans le blog
    1
    Par défaut
    Salut,


    Pour le premier point, renseigne toi sur le fonctionnement de l'EDT (Event Dispatch Thread).

    En gros tout ce qui touche à l'interface doit s'effectuer sur l'EDT, et tous les traitements "long" ou "bloquant" doivent d'effectuer sur un thread à part...

    Regardes du coté du SwingWorker qui est là pour gérer ce genre de problème

    a++

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France, Yvelines (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 61
    Par défaut
    Je viens de faire quelques recherches sur le SwingWorker.
    Il semble à première vue adapter à mon problème 1.

    Si j'ai bien compris, lorsque je double clique sur mon fichier, je me retrouve dans l'EDT. Du coup, comme je lance le décompressage et qu'il dure un certain temps, il y a un bloquage de l'interface graphique (et de la VueAttente) et c'est pourquoi il faudrait lancer le décompressage dans un autre thread.

    Quelque chose m'échape néanmoins.
    Il est dit qu'il faut mettre les traitements long dans la méthode doInBackground(). Donc je suppose que ma méthode de compressage devrait se trouver dedans.
    Si je suis dans l'EDT lorsque j'arrive dans le Controleur, je n'ai pas besoin d'appelé InvokeLater du coup ?!
    Aussi, où est ce que je déclare ma fenêtre VueAttente ?

    J'ai vu dans l'exemple du lien que j'ai donné que la personne faisait non seulement le traitement long dans doInBackground() mais aussi mettait à jour son affichage. Est-ce normal de mélanger les deux ?

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juin 2009
    Messages
    61
    Détails du profil
    Informations personnelles :
    Localisation : France, Yvelines (Île de France)

    Informations forums :
    Inscription : Juin 2009
    Messages : 61
    Par défaut
    Bon j'ai résolu le problème du thread a l'aide du SwingWorker.

    Pour ceux qui souhaite faire une fenêtre d'attente :
    Il faut déclarer votre vue dans le controleur (implements MouseListener, ActionListener etc...) et lancer le traitement long dans une classe qui hérite de SwingWorker dans la méthode doInBackground()
    Pour mettre à jour votre fenêtre (comme rajouter un "." toutes les secondes) et pour ne pas bloquer l'EDT, déclarer un thread et mettez à jour votre fenêtre dans ce dernier.

    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
    VueAttente vueAttente = new VueAttente("Decompression");
    Traitement t = new Traitement(); // classe héritant de SwingWorker
    t.execute();
     
    new Thread(new Runnable() {
    	run() {
    		while(running) { // tant que le swingworker n'a pas achevé sa tache de fond
    			try {
    				Thread.sleep(1000); // dors 1 seconde
    			catch(Exception e) {}
    			vueAttente.setLabel("."); // met à jour le label de la fenêtre d'attente
    		}
    		vueAttente.dispose(); // on quitte la fenêtre dès que c'est fini
    	}
    }).start();
    Je mets à jour VueApplication dans la méthode done() du SwingWorker, ça marche très bien. Pour la laisser au premier plan, je vais voir du côté de setAlwaysOnTop(true);


    Sinon, aucune idée pour le deuxième problème concernant les GridBagLayout ?

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

Discussions similaires

  1. Problème thread et fonction récursive
    Par cryptorchild dans le forum Langage
    Réponses: 3
    Dernier message: 27/09/2006, 12h19
  2. Problème thread Boost
    Par TuRn3r dans le forum Autres éditeurs
    Réponses: 1
    Dernier message: 01/06/2006, 18h34
  3. Problème Thread et Scan de dossiers en C
    Par tptiben dans le forum Windows
    Réponses: 8
    Dernier message: 15/05/2006, 18h25
  4. [Swing] Problème avec les GridBagLayout
    Par CrazySeb dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 28/04/2006, 14h47
  5. Problème Thread
    Par Royd938 dans le forum Général Dotnet
    Réponses: 5
    Dernier message: 07/04/2006, 09h10

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