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

Agents de placement/Fenêtres Java Discussion :

[JProgressBar] Fenetre gelée


Sujet :

Agents de placement/Fenêtres Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Par défaut [JProgressBar] Fenetre gelée
    Salut,

    Je suis ammené à faire une copie d'un fichier local vers un serveur distant.

    J'ai donc trouvé une fonction qui marche parfaitement, mais quand on copie des gros fichiers, celà prend du temps. Du coup, j'aimerai faire un JProgressBar et l'intégrer à cette fonction.

    Voici ce que j'ai fait :

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
     
    		private void copyFile(File in, File out) 
    	    {
    	    	FileChannel inChannel=null;
    	    	FileChannel outChannel=null;
    	    	try
    	    	{
     
    	    		JProgressBar progressBar = new JProgressBar();
     
    				/*progressBar.setIndeterminate(true);
     
    				progressBar.setVisible(true);*/
     
    				//progressBar.setIndeterminate(false);
     
     
     
     
    	            inChannel = new FileInputStream(in).getChannel();
    	       	 	outChannel = new FileOutputStream(out).getChannel();
    	            /**specially for windows cases**/
     
    	            // magic number for Windows, 64Mb - 32Kb)
    	           int maxCount = (64 * 1024 * 1024) - (32 * 1024);
    	           long size = inChannel.size();
    	           long position = 0;
     
    	           progressBar.setStringPainted(true);
    	           progressBar.setMaximum((int)(size/maxCount));
    	           progressBar.setMinimum(0);
    	           progressBar.setValue(0);
     
    	           final JDialog jd=new JDialog((JFrame)null, true);
    	           jd.setSize(400,150);
    	           jd.add(progressBar);
    	           jd.setLocationRelativeTo(null);
     
     
    				new Thread(new Runnable()
    				{
    					public void run()
    					{
    						System.out.println("setting progressbar visible");
    						jd.setVisible(true);
    					}
    				}
    				).start();
     
     
     
    	           //progressBar.setVisible(true);
     
    	           while (position < size) 
    	           {
     
    					position += inChannel.transferTo(position, maxCount, outChannel);
    					progressBar.setValue(new Long(position).intValue());
    					progressBar.setString(position/maxCount+"/"+size/maxCount);
    	            }
     
    	            jd.dispose();
    	            //progressBar.close();
    	            System.out.println("end of copy");
    	        }catch(Exception e)
    	    	{
    	    		e.printStackTrace();
    	    	}
    	        finally 
    	        {
     
    	        }
     
     
    	    }
    Je précise que cette fonction est appelée lors d'un clic de bouton, dans un ActionListener. Pour afficher ma jdialog sans que celà ne gèle le traitement, je le met visible dans un thread approprié, puisque l'appel à invokeLater de SwingUtilities donnerai un affichage apres le traitement (qui est appelé dans un event, je le rappelle).

    Or, le problème est qu'on se retrouve avec une jdialog qui s'affiche mais dans laquelle rien n'est affiché pendant le traitement (bug d'affichage "gel" classique à java) et lorsque le traitement est fini, elle s'affiche bien si on ne dispose pas, sinon elle dispose tout simplement.

    J'aimerai savoir pourquoi, et comment je peux y remédier pour bien afficher mon traitement.

    Merci

    Fred

  2. #2
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    Hello,

    ce n'est pas le setvisible qu'il faut mettre dans un thread, mais bien le traitement de copie

    et ensuite utilise invokeandwait pour repainter les composants swing

  3. #3
    Membre éprouvé
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Par défaut
    Salut,

    Merci de ta réponse!

    Voici mon code, modifié en conséquence (c'est ce que j'avais fait à la base) :

    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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
     
    		private void copyFile(File in, File out) 
    	    {
     
    	    	try
    	    	{
     
    	    		final JProgressBar progressBar = new JProgressBar();
     
    				/*progressBar.setIndeterminate(true);
     
    				progressBar.setVisible(true);*/
     
    				//progressBar.setIndeterminate(false);
     
     
     
    	    		final FileChannel inChannel=new FileInputStream(in).getChannel();
    	    		final FileChannel outChannel=new FileOutputStream(out).getChannel();
    	            /**specially for windows cases**/
     
    	            // magic number for Windows, 64Mb - 32Kb)
     
     
    	           progressBar.setStringPainted(true);
    	           //
    	           progressBar.setMinimum(0);
    	           progressBar.setValue(0);
     
    	           final JDialog jd=new JDialog((JFrame)null, true);
    	           jd.setSize(400,150);
    	           jd.add(progressBar);
    	           jd.setLocationRelativeTo(null);
     
     
    				SwingUtilities.invokeAndWait(new Runnable()
    				{
    					public void run()
    					{
    						try
    						{
    							int maxCount = (64 * 1024 * 1024) - (32 * 1024);
    				            long size = inChannel.size();
    				            long position = 0;
     
    				           progressBar.setMaximum((int)(size/maxCount));
    							while (position < size) 
    				           {
     
    								position += inChannel.transferTo(position, maxCount, outChannel);
    								progressBar.setValue(new Long(position).intValue());
    								progressBar.setString(position/maxCount+"/"+size/maxCount);
    				            }
     
    				            jd.dispose();
    				            //progressBar.close();
    				            System.out.println("end of copy");
    						}catch(Exception e)
    						{
    							e.printStackTrace();
    						}
     
    					}
    				}
    				);
     
     
     
    	           //progressBar.setVisible(true);
     
     
    	        }catch(Exception e)
    	    	{
    	    		e.printStackTrace();
    	    	}
    	        finally 
    	        {
     
    	        }
     
     
    	    }
    Et l'exception levée :

    Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWai
    t from the event dispatcher thread
    at java.awt.EventQueue.invokeAndWait(EventQueue.java:980)
    at javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1323)
    at XMLTree$AttachFile.copyFile(XMLTree.java:3645)
    at XMLTree$AttachFile.actionPerformed(XMLTree.java:3604)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:19
    95)
    Je suppose que c'est parceque j'appelle la fonction copy dans un event non ?

    F.

  4. #4
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    En pseudo-code, ça donnerait un truc comme ceci selon moi:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    dans le event:
     
    - créer un progress dialog
    - le rendre visible
    - lancer le thread de traitement (copie)
     
    dans le thread
    - a chaque boucle, incrémenter la progression de la barre
    - invoquer invokeandwait avec un runnable qui ne fait que le repaint de la barre

  5. #5
    Expert confirmé
    Avatar de sinok
    Profil pro
    Inscrit en
    Août 2004
    Messages
    8 765
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2004
    Messages : 8 765
    Par défaut
    Cadeau de type FAQ: http://java.developpez.com/faq/gui/?...raitement_long

    Et re cadeau de type tuto: http://gfx.developpez.com/tutoriel/j...ing-threading/

    Et re re cadeau de type tuto pour une solution bien foutue: http://rom.developpez.com/java-swingworker/

  6. #6
    Membre Expert

    Homme Profil pro
    Consultant informatique
    Inscrit en
    Janvier 2004
    Messages
    2 301
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Janvier 2004
    Messages : 2 301
    Par défaut
    Citation Envoyé par sinok Voir le message
    Cadeau de type FAQ...
    Et re cadeau de type tuto...
    Et re re cadeau de type tuto ...
    c'est noël!


  7. #7
    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,



    Tu mélanges EDT et threads.

    Pour rappel l'EDT est le thread graphique dédié à gérer l'interface graphique (affichage, évènements, etc.), et il ne doit être exécuté QUE pour cela !

    invokeLater() et invokeAndWait() permettent d'exécuter du code dans l'EDT, mais cela ne doit contenir que du code modifiant l'interface graphique et en aucun cas des traitements divers, et surtout pas des traitement potentiellement lourds...

    Il faut voir l'EDT comme un thread qui tourne en boucle sur une pile d'action à exécuté, contenant les mises à jours de l'affichage, les évènements et les appels à invokeLater()/invokeAndWait(). Si tu effectues un traitement lourd dedans tu décaleras tout le reste et l'interface sera figé...


    En clair tu dois utiliser un thread pour le copie des fichiers, et invokeLater()/invokeAndWait() pour la mise à jour de l'interface. Or tu fais exactement l'inverse...



    SwingWorker permet de faciliter tout cela, en séparant bien le code qui doit être exécuté dans un thread séparé de celui qui devra être dans l'EDT...


    Sinon il y a aussi ProgressMonitor qui permet d'afficher une fenêtre de progression assez simplement...


    a++

  8. #8
    Membre éprouvé
    Avatar de mavina
    Homme Profil pro
    Développeur Java
    Inscrit en
    Octobre 2004
    Messages
    1 812
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Chine

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Conseil

    Informations forums :
    Inscription : Octobre 2004
    Messages : 1 812
    Par défaut
    Résolu et fonctionnel, merci !

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

Discussions similaires

  1. [JPROGRESSBAR] fermeture de la fenetre principal
    Par dark2 dans le forum AWT/Swing
    Réponses: 1
    Dernier message: 19/10/2006, 09h16
  2. [VB6] [Système] Récupérer le contenu d'une fenêtre DOS
    Par Nounours666 dans le forum VB 6 et antérieur
    Réponses: 16
    Dernier message: 18/11/2004, 17h38
  3. Cacher fenetre
    Par Captain Fizzou dans le forum GLUT
    Réponses: 2
    Dernier message: 25/08/2002, 18h22
  4. Réponses: 3
    Dernier message: 22/07/2002, 15h19
  5. gérer les jpg dans une fenetre directdraw???
    Par Anonymous dans le forum DirectX
    Réponses: 1
    Dernier message: 14/06/2002, 14h39

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