Je d=E9bute avec les threads et j'ai un peu de mal =E0 lire le contenu
d'une variable d'un thread par un autre thread.
Plus pr=E9cis=E9ment, j'ai fait un programme compos=E9 de 3 classes :
- une classe player qui ex=E9cute un thread pour lire un fichier son via
JavaSound. Dans cette classe j'ai mis un attribut value qui correspond
au pourcentage d'avancement du fichier lu.
- une classe JProgress qui correspond =E0 une ProgressBar qui va lire la
valeur de l'attribut value pour mettre =E0 jour la progressBar. Cette
classe utilise aussi un thread diff=E9rent et se base sur l'exemple
donn=E9 dans la FAQ Java concernant les ProgressBar.
- une classe GUI qui contient un player et une JProgressBar.
Plus pr=E9cis=E9ment voici les parties de mes classes concern=E9es par les
threads :
- classe Player (qui impl=E9mente Runnable) :
[CODE]
/**
* m=E9thode run du thread
*/
public void run(){
// on r=E9cup=E8re le format de ce fichier
AudioFormat audioFormat =3D audioInputStream.getFormat();
// on essaie d'ouvrir la ligne n=E9cessaire =E0 la lecture.
try
{
line.open(audioFormat);
}
catch (LineUnavailableException e)
{
e.printStackTrace();
System.exit(1);
}
catch (Exception e)
{
e.printStackTrace();
System.exit(1);
}
// on d=E9marre la ligne, ce qui permettra au flux d'=EAtre redirig=E9
// sur la carte Son
line.start();
// on r=E9cup=E8re les donn=E9es =E0 lire
ArrayList<byte[]> listData =3D getDataOutput();
int j =3D 0, k =3D 0;
// on lit chacune d'entre elles
for(byte[] part : listData){
int taille =3D sizes.get(j);
for(int i =3D 0; i < taille; i+=3D20){
/* C'EST ICI QUE SE FAIT L'ACCESS =E0 l'attribut value de player */
value =3D k * 100 / size;
line.write(part, i, 2);
k+=3D20;
}
//line.write(part, 0, part.length);
j++;
}
// on s'assure de bien vider les parties restant =E0 lire
line.drain();
// fermeture de la ligne
line.close();
}[/CODE]
- classe JProgress :
[CODE]
public class JProgress extends JProgressBar implements Runnable
{
/**
*
*/
private static final long serialVersionUID =3D 1L;
private boolean isStarted;
private int value;
/**
* Player associ=E9 =E0 la progressBar
*/
private Player player;
public void setValue(int value){
this.value =3D value;
}
public void setStarted(boolean started){
isStarted =3D started;
}
public void launch(){
// si progressBar non d=E9mar=E9e
if(!isStarted){
isStarted =3D true;
Thread t =3D new Thread(this);
t.start();
}
}
// methode de l'interface Runnable
// lance un nouveau thread qui va executer le code de la methode
longTraitement
public void run(){
/* ICI ON TENTE D'ACCEDER =E0 l'attribut value du player associ=E9 via un
getter */
while(player.getValue() < 100)
majProgress();
}
// methode qui met a jour la JProgressBar par le processus
d'evenement
// Pourquoi obliger l'execution de cette methode par le processus
d'evenement ?
// -> Cf : la docs du tutoriel de Sun section : "Threads and Swing"
// http://java.sun.com/docs/books/tutorial/uiswing/mini/threads.html
public void majProgress ()
{ if ( SwingUtilities.isEventDispatchThread () )
{
/* ON TENTE DE MODIFIER LA VALEUR DE la progressbar en acc=E9dant =E0
l'attribut value du player associ=E9 */
setValue(player.getValue());
}
else
{ Runnable callMAJ =3D new Runnable ()
{ public void run ()
{ majProgress ();
}
};
SwingUtilities.invokeLater (callMAJ);
}
}
}
[/CODE]
- classe GUI (je mets juste la m=E9thode qui d=E9clenche les 2 threads en
gros) :
[CODE]
public void play(){
if(player !=3D null && player.getFile() !=3D null){
// on lance la lecture sur le player
player.play();
// on lance la progress bar
progress.launch();
}
}
[/CODE]
Donc voil=E0, en lan=E7ant mon code la progressBar reste bloqu=E9e =E0 0%. =
Il
y a =E9videmment quelque chose que j'ai mal fait parce qu'une fois le
thread de lecture fini la progressbar ne se met m=EAme pas =E0 jour =E0 100%
c=F4t=E9 du thread de JProgress bien que la valeur de value soit =E0 100 =
=E0
ce moment l=E0.
Quelqu'un pourrait-il m'aider et m'aiguiller pour r=E9soudre ce
probl=E8me ?