JProgressBar qui affiche directement 100% :( [RESOLU] - Java - Programmation
Marsh Posté le 21-09-2009 à 03:16:16
C'est ici que tu devrais utiliser invokeLater()
Bon alors... d'abord ta JProgressbar tu dois lui spécifier un minimum et un maximum. Par défaut ça va de 0 à 100. Toi tu dois spécifier que le maximum est la valeur this.jpbmax.
Ensuite, si ta méthode downloadFile() est démarrée dans le thread graphique (en réponse à un clic sur un bouton, un événement clavier ou autres), tu dois changer ça. Il faut que la méthode downloadFile() soit lancée dans un nouveau Thread sinon l'interface graphique va se "figer" pendant toute la durée du download et se débloquer à la fin. Raison pour laquelle tu passes de 0 à 100% en une étape.
Troisièmement, tu dois exécuter le code de la méthode setValeur() avec SwingUtilities.invokeLater(). Il s'agit en effet du code qui met à jour l'interface graphique donc il doit s'exécuter dans le thread graphique et invokeLater te permet de lancer des actions dans le thread graphique (puisqu'on est dans le thread qui download).
Enfin, tu devrais écrire directement le fichier sur le disque sans le stocker entièrement en mémoire! Surtout si ton fichier fait plusieurs dizaines ou centaines de MégaOctets. Tu dois juste allouer un buffer (je dirais de 16, 32 ou éventuellement 64 KiloOctets) et transférer les données de l'inputstream vers l'outputstream au fur et à mesure qu'elles arrivent, via ce même buffer. Bien sûr, si tu vois que jpbmax est plus petit que la taille de ton buffer, alors alloue un buffer de taille jpbmax pour ne pas gaspiller de mémoire.
Marsh Posté le 21-09-2009 à 04:22:40
hihihi tu es un vrai noctambule
Bon je vais me renseigner sur les threads et invokeLater car j'ai des carences a combler après je pense que je comprendrais mieux
Merci de tes infos que je garde sous le coude.
concernant la jprogressbar je l'initialise correctement :
Code :
|
et pour le fichier il ne sera pas gros donc je peux le stocker en mémoire pour le moment ! mais en effet ta remarque est juste
Marsh Posté le 21-09-2009 à 15:23:07
Si le fichier n'est pas gros... quelle est l'intérêt d'une progressBar?
Marsh Posté le 21-09-2009 à 18:31:19
l'intérêt est juste de savoir me servir de la jprogressbar. Je débute en Java et donc j'étudie tout ce qui me parait interessant. Dans ce cas la ca me fait aborder les notions de threads notament
Donc concernant la JProgressBar ce que je ne comprend pas c'est que un thread est demarré par la méthode start et l'OS a un moment donné va donner du temps processeur a ce thread et executer la methode run() de la classe fille. Mais quand je veux 2 thread qui executent 2 fonctions différentes mais néanmoins liées (l'un est l'affichage graphique et l'autre le download du fichier) je dois obligatoirement faire 2 classes dans 2 fichiers différents ? je trouve cela lourd
Tous les tutoriaux que je trouve les 2 thread partage la meme methode run et il partage une variable membre de cette classe. Ce qui n'est pas mon cas. Peux tu me confirmer ?
Marsh Posté le 22-09-2009 à 00:38:48
Tu ne dois pas faire 2 classes bien au contraire, tu peux déclarer ta classe Runnable et y implémenter une méthode run() ou bien définir un Thread/Runnable directement dans le code:
Code :
|
Le code ci-dessus définit et démarre un nouveau Thread. Il n'est pas nécessaire d'en garder une référence sauf si tu veux pouvoir appeler interrupt() dessus plus tard.
Ici les 2 threads partagent une variable aussi: c'est le nombre de bytes actuellement lus. Ce nombre est mis à jour par le thread qui download et il est aussi utilisé par le thread graphique pour calculer ce que la progressBar doit afficher.
Marsh Posté le 22-09-2009 à 00:52:47
Super !!
Je commence à comprendre la notion de thread et l'interface runnable ! (enfin c'est tellement plus facile avec la solution )
Ya aussi la classe abstraite SwingWorker que l'on peut utiliser.
PS : tu fais comment pour que ton texte dans la balise code apparaisse avec des couleurs ?
Marsh Posté le 22-09-2009 à 01:12:14
Oui là je le fais à la "mano" mais effectivement SwingWorker peut simplifier la tâche en exécutant des méthodes dédiées que tu redéfinis dans des threads différents. C'est une classe d'aide, nouveauté de Java 1.6. L'idéal est de lire la documentation de la classe, tout est expliqué. Dans ton cas, la méthode doInBackground() serait celle qui effectue le téléchargement. La méthode process() est appelée tout à la fin du téléchargement dans le thread graphique et reçoit le résultat.
Quoique je ne trouve pas que le code soit tellement simplifié avec SwingWorker puisque tu devrais créer également un "PropertyChangeListener" qui serait notifié à chaque étape du téléchargement afin de mettre à jour la progressBar. Cela fait beaucoup de tuyauterie.
Pour utiliser la coloration syntaxique du code java j'utilise les balises BBCode (code==java)(/code) où les parenthèses doivent être remplacées par des [].
Marsh Posté le 22-09-2009 à 01:21:53
Bon je me rends compte que je ne comprends pas tout . Ya encore des choses qui m'échappe. Je vais devoir bosser dessus
Je réflechis en séquentiel et pas en évenementiel. J'ai pas mal de mal
Merci pour le bbcode, ca apparait niquel
Marsh Posté le 22-09-2009 à 01:35:53
Ah c'est sûr que les interfaces graphiques, c'est de l'événementiel à 100%! C'est ce qu'on doit apprendre en dernier après tout le reste. Et puis il y a aussi des gens qui ne comprennent jamais la notion de Thread, un peu comme ceux qui ne parviennent pas à comprendre la notion de récursivité.
Marsh Posté le 22-09-2009 à 01:38:47
J'ai eu du mal avec la récursivité quand on m'a invité à mon taf à en faire pour un forum. Mais ensuite une fois qu'on comprends l'empilement et le dépilement ca roule
Pareil ici je pense, j'ai encore un peu de mal, mais le vocabulaire et les notions théoriques commencent à rentrer après je pense que je vais "voir" le code beaucoup plus facilement
Marsh Posté le 22-09-2009 à 01:45:47
Une petite question :
Code :
|
J'ai découpé dans une méthode le téléchargement. Comment je peux passer la référence de guiUpdater au lieu d'avoir une copie locale dans la méthode "uneMethode" ?
Marsh Posté le 22-09-2009 à 01:49:09
Bon apparemment tous les objets sont passés par référence
Marsh Posté le 22-09-2009 à 02:49:20
Bon j'ai réduit le code et cela marche très bien
Dans downloadfile, j'appelle directement ma méthode qui met à jour la JProgressBar.
[code==java]public void traitement(){
new Thread() {
public void run() {
downloadFile();
}
}.start();
}[/java]
Quel était l'intérêt de ta méthode ? Doit on absolument implementer la classe runnable pour la mise à jour graphique ? pourquoi ne pas laisser le nouveau thread gérer cela ?
Hum, j'ai changé le fichier qui est téléchargé par un fichier de 4Mo (au lieu de 20Ko) est ce pour cela que maintenant je n'ai pas le saut à 100% directement ?
Marsh Posté le 22-09-2009 à 18:33:15
En java les objets sont tous passés par référence et les types primitifs (int, long, float, double, boolean) sont tous passés par valeur.
Les instructions qui modifient l'interface graphique doivent être exécutées dans le thread de Swing. je ne dis pas ça pour t'emmerder, c'est écrit dans la documentation. Maintenant peut-être que dans ton cas ça fonctionne pour une raison ou une autre mais ce n'est pas la bonne façon de faire.
Et oui on est obligé de passer par une classe qui implémente Runnable en Java car il n'existe pas de pointeurs vers des fonctions dans ce langage.
Marsh Posté le 20-09-2009 à 03:02:13
Bonjour,
Voila j'ai une JProgressBar (dans un JPanel d'un JFrame) pour lire un fichier d'un serveur distant. Mais ma JProgressBar m'affiche 100% dessuite
Pour la lecture du fichier j'utilise un getInputStream.
J'ai l'impression qu'il faut utiliser 2 threads l'un pour afficher la JProgressBar et l'autre pour rappatrier le fichier mais je ne saisi pas la notion sous jacente
Please
Message édité par Yop69 le 23-09-2009 à 22:17:14