La JProgressBar ne m'affiche pas de bar de progression

La JProgressBar ne m'affiche pas de bar de progression - Java - Programmation

Marsh Posté le 23-09-2009 à 22:19:22    

Bonjour,
 
Comme vous pouvez le voir ci-dessous, la JProgressBar malgré que le texte à l'intérieur s'incrémente bien, ne se lance pas :(
http://photoyop.free.fr/a/c.png
Savez vous d'ou cela vient ? ou c'est normal ?


Message édité par Yop69 le 23-09-2009 à 22:20:02
Reply

Marsh Posté le 23-09-2009 à 22:19:22   

Reply

Marsh Posté le 24-09-2009 à 01:21:39    

Tu as respecté les threads?
 
Sinon joli screenshot :)

Reply

Marsh Posté le 24-09-2009 à 01:24:22    

Oui oui j'ai remis ton code (je suis assez maniaque la-dessus :) comme l'indentation d'ailleurs  :D  )
Mais ça ne résoud pas ma question, normalement (peut être que je me trompe), on indique à la JProgressBar la nouvelle valeur et hop la barre avance non ? la il n'y a que le texte (19%) qui change  :(


Message édité par Yop69 le 24-09-2009 à 02:03:41
Reply

Marsh Posté le 24-09-2009 à 02:11:41    

Oui, il suffit d'appeler setValue() dans le thread graphique (et ne pas le bloquer avec une autre opération).
Mais il faudrait voir le code pour savoir ce que tu fabriques. Et vérifier si la valeur que tu passes à setValue est valide aussi.


Message édité par cbeyls le 24-09-2009 à 02:16:30
Reply

Marsh Posté le 24-09-2009 à 02:15:59    

Code :
  1. public void setValeur(){
  2.         
  3.         System.out.println(this.deplacement +" | "+this.jpbmax);
  4.         
  5.         this.jpb.setValue(this.deplacement);
  6.         this.jpb.setString(this.deplacement * 100 / this.jpbmax +"%" );
  7.         
  8.         //this.jpbCdr.paintComponents(this.jpbCdr.getGraphics());
  9.     }
  10.  
  11. public void traitement(){
  12.         
  13.         new Thread(null,null,"download" ) {
  14.             public void run() {
  15.                 Runnable guiUpdater = new Runnable() {
  16.                     public void run() {
  17.                         setValeur();
  18.                     }
  19.                 };
  20.                 
  21.                 informUser( downloadFile(guiUpdater) );
  22.             }
  23.         }.start();
  24.     }
  25.  
  26. public boolean downloadFile(Runnable guiUpdater) {
  27.         URLConnection connection = null;
  28.         InputStream is = null;
  29.         FileOutputStream destinationFile = null;
  30.         String pathfile = this.tabXml[ this.indexMaj ][2] + "/" + this.tabXml[ this.indexMaj ][3];
  31.         boolean ret = false;
  32.         
  33.         try {
  34.             //On crée l'URL
  35.             URL url = new URL( pathfile );
  36.  
  37.             //On crée une connection vers cet URL
  38.             connection = url.openConnection( );
  39.  
  40.             //On récupère la taille du fichier
  41.             this.jpbmax = connection.getContentLength();
  42.  
  43.             //Si le fichier est inexistant, on lance une exception
  44.             if(this.jpbmax == -1) throw new IOException("Fichier vide" );
  45.             
  46.             //On récupère le stream du fichier
  47.             is = new BufferedInputStream(connection.getInputStream());
  48.  
  49.             //On prépare le tableau de bits pour les données du fichier
  50.             byte[] data = new byte[ this.jpbmax ];
  51.  
  52.             //On déclare les variables pour se retrouver dans la lecture du fichier
  53.             int currentBit = 0;
  54.             this.deplacement = 0;
  55.             
  56.             //Tant que l'on n'est pas à la fin du fichier, on récupère des données
  57.             while(this.deplacement < this.jpbmax){
  58.                 currentBit = is.read(data, this.deplacement, data.length-this.deplacement);    
  59.                 if(currentBit == -1) break;
  60.                 
  61.                 this.deplacement += currentBit;
  62.                 SwingUtilities.invokeLater(guiUpdater);
  63.                 if(this.interrupted) return ret;
  64.             }
  65.             System.out.println("e" );
  66.             //Si on n'est pas arrivé à la fin du fichier, on lance une exception
  67.             if(this.deplacement != this.jpbmax) throw new IOException("Le fichier n'a pas été lu en entier (seulement " + deplacement + " sur " + this.jpbmax + " )" );
  68.                     
  69.             //On crée un stream sortant vers la destination
  70.             destinationFile = new FileOutputStream( "tmp.jar" );
  71.  
  72.             //On écrit les données du fichier dans ce stream
  73.             destinationFile.write(data);
  74.  
  75.             //On vide le tampon et on ferme le stream
  76.             destinationFile.flush();
  77.  
  78.         } catch (MalformedURLException e) { System.err.println("Problème avec l'URL : " + pathfile); }
  79.         catch (IOException e) { e.printStackTrace(); }
  80.         finally {
  81.             try {
  82.                 
  83.                 if(this.interrupted) return ret;
  84.                 
  85.                 is.close();
  86.                 destinationFile.close();
  87.                 ret = true;
  88.             } catch (IOException e) {
  89.                 e.printStackTrace();
  90.             }
  91.         }
  92.         
  93.         return ret;
  94.     }


 
 :sweat:  

Reply

Marsh Posté le 24-09-2009 à 02:38:48    

Que fait la méthode informUser ? Mon petit doigt me dit qu'elle appelle une fonction graphique alors que tu es dans le thread de download! Bref, ta méthode informUser, si elle affiche des infos ou autres, devrait être appelée dans un invokeLater() aussi.
Sinon, à part la forme un peu exotique du code, le reste me semble correct.
 
Petite précision quand même: quand connection.getContentLength() renvoie -1, ce qui peut arriver avec de nombreux serveurs web, ça ne veut pas dire que le fichier est vide mais simplement que la taille du fichier final n'est pas connue. Tu auras déjà remarqué que quand tu télécharges certains fichiers sur le net, firefox t'indique le nombre de bytes actuellement téléchargés avec une taille totale de fichier inconnue.

Reply

Marsh Posté le 24-09-2009 à 02:44:53    

Encore une  chose: ton bloc finally est mal écrit, car si le thread est interrompu tu ne fermes pas les fichiers.

Reply

Marsh Posté le 24-09-2009 à 02:55:11    

Alors concernant informUser c'est juste une popup ou non avertissant la fin du download

Code :
  1. private void informUser(boolean b){
  2.         
  3.         if(this.interrupted){
  4.             this.jpbCdr.dispose();
  5.         } else if( b ){
  6.             this.jl.setText("Téléchargement effectué avec succès." );
  7.             this.jb.setText("Redemarrer l'application" );
  8.         } else {
  9.             this.jl.setText("Un problème est survenu lors du téléchargement." );
  10.         }
  11.         
  12.         this.jb.addActionListener( new ActionListener(){
  13.             public void actionPerformed(ActionEvent e){
  14.                 System.out.println(buttonJl().getName());
  15.                 
  16.                 if( buttonJl().getName() == "" ){
  17.                     ;
  18.                 }else{
  19.                     ;
  20.                 }
  21.             }
  22.         });
  23.     }


 
Concernant connection.getContentLength() == -1 tu m'apprends un truc concernant la taille du fichier inconnue.
Et pour le bloc finally, oui j'ai juste a mettre la fermeture du fichier avec le return ret
 
Donc toujours rien pour ma JProgressBar  :sweat:  

Reply

Marsh Posté le 24-09-2009 à 03:15:15    

Non je ne sais pas pourquoi la progressbar ne s'affiche pas.
 
Et pour informUser, on dirait que tu n'as toujours pas compris: on ne peut pas appeler des méthodes qui modifient l'interface graphique dans un thread autre que le thread graphique de SwinG!
 
Ta méthode informUser contient du code qui modifie le text d'un label et ajoute un listener -> ce code doit être exécuté dans un Runnable appelé par SwingUtilities.invokeLater(). Il faudrait peut-être regrouper un peu le code au lieu de l'éclater dans de nombreuses méthodes appelées par différents threads pour y voir plus clair. Ou alors utilise SwingWorker.


Message édité par cbeyls le 24-09-2009 à 03:17:24
Reply

Marsh Posté le 24-09-2009 à 03:38:53    

Ok, tout ce qui touche à l'interface graphique doit passer par le thread SwingUtilities. Ce que je ne comprend pas bien c'est que ce thread est situé dans le thread de traitement. Cela m'embrouille, concretement, je n'arrive pas à voir comment cela se passe. Un thread dans un thread.
 
Par contre, mon appli lors de l'appel à main, je fais appel a mon constructeur de classe ou j'initialise le jpanel, je jmenu, jmenuitem avec bien sur la gestion des evenements. Tout cela aussi je dois le passer dans un SwingUtilities ?  :sweat: (aïe aïe aïe je crains que oui pourtant tous les exemples du net ne m'en parle pas de ca  :fou: )
 

Reply

Marsh Posté le 24-09-2009 à 03:38:53   

Reply

Marsh Posté le 24-09-2009 à 14:44:58    

Je pense que c'est permis d'initialiser le GUI dans le main() puisque tu construis le GUI, tu ne l'affiche pas encore. Ensuite tu affiches la fenêtre principale en faisant setVisible(true) et là techniquement, tout ce qui suit et qui modifie le GUI doit être fait avec un invokeLater() sinon il risque de ne pas s'afficher correctement.
 
Un thread n'est pas exécuté "dans" un thread. Les threads sont autonomes. Le thread graphique de Swing existe déjà avant que tu crées ton thread de téléchargement. Quand tu appelles invokeLater, tu ne crées pas de nouveau thread, tu demandes à java de postposer l'exécution du Runnable dans la file de traitement du thread graphique de Swing qui est toujours en cours d'exécution tant qu'il y a une fenêtre ouverte.

Reply

Marsh Posté le 24-09-2009 à 20:17:30    

Merci pour ces informations c'est très gentil. Tu parles de la file de traitement du thread graphique de Swing c'est pas ce qu'on appelle l'EDT ?

Reply

Marsh Posté le 24-09-2009 à 22:30:37    

Oui, c'est l'Event Dispatch Thread.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed