Utilisation d'un SwingWorker

Résolu
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012 - 2 avril 2012 à 20:24
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012 - 4 avril 2012 à 16:12
Bonjour,

Je suis debutant en Programmation Objet et en java .
Je me suis lancé dans la programmation d'un pac man .

Mais voila je butte sur un obstacle que je ne comprend pas vraiment .

voila le resumer de mes classes .

Fenetre : Création de l'affichage de la fenetre et du conteneur .
ModeleDuJeu : classe dissociant l'affichage , du calcul du jeu
Personnage : classe permettant d'afficher une image et me de la faire ce deplacer .


Enumeration Direction : enumere les differentes direction .

Pour le moment , je n'est pas programmer le deplacement en fonction de la fleche voulu .
je veus juste faire un petit test . Bon voila le probleme : lorsque je lance l'application ( sans le SwingWorker ) j'ai ce message d'erreur :" Exception in thread "Thread-1" java.lang.NullPointerException
at Personnage.mouvement(Personnage.java:67)
at Personnage.calcul(Personnage.java:82)
at ModeleDuJeu.calcul(ModeleDuJeu.java:22)
at Fenetre$2.run(Fenetre.java:84)
at java.lang.Thread.run(Unknown Source) "

En faisant des recherches j'ai trouver une solution le SwingWorker , mais je ne sait pas vraiment l'utiliser ...
Lorsque je lance l'application avec je n'est plus le message d'erreur mais l'image ne ce deplace pas pour autant .
J'ai donc lancé le mode Debug , l'image ce deplace mais fait seulement le swingworker ( ou j'ai mis le calcul du jeu ) et par dans les choux.

donc le repaint ne s'execute pas .


voila les differentes classes en question que j'utilise .


Classe Fenetre :

import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;

import java.awt.Graphics;



public class Fenetre extends JFrame implements Constantes {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private ModeleDuJeu modele;

//constructeur
public Fenetre(){
// titre de la fenêtre
super("Pac-Like By Ben");
// créer le modèle du jeu
this.modele = new ModeleDuJeu();
// fermeture de l'application lorsque la fenêtre est fermée
setDefaultCloseOperation(EXIT_ON_CLOSE);
// pas de redimensionnement possible de la fenêtre
setResizable(false);
// créer un conteneur qui affichera le jeu
final JPanel content = new JPanel(){

/**
 * 
 */
private static final long serialVersionUID = 1L;

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// affichage du modèle du jeu
Fenetre.this.modele.affichage(g);
}


};
// dimension de ce conteneur 
content.setPreferredSize(new Dimension( NBRE_DE_COLONNES * CASE_EN_PIXELS,
NBRE_DE_LIGNES * CASE_EN_PIXELS));
// ajouter le conteneur à la fenêtre
setContentPane(content);



// Créer un thread infini
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// gestion de l'EDT eventDispatchThread

SwingWorker sw = new SwingWorker() {

protected Object doInBackground() throws Exception {
//content.repaint();
                        // temporisation
//Fenetre.this.modele.calcul();
try {

Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();

}

return null ;
}

};// fin du SwingWorker
 sw.execute();
while (true) { // boucle infinie
// à chaque fois que la boucle est exécutée, la
// méthode de calcul du jeu est appelée.
// Comme la boucle est infinie, la méthode de calcul
// sera appelée en cycle perpétuel.

Fenetre.this.modele.calcul();
// demander à l'EDT de redessiner le conteneur
content.repaint();
// temporisation
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();

}

}
}
});
// lancer le thread
thread.start();

}

// Lancement du jeu 
public static void main(String[] args) {
// création de la fenêtre , instenciation
Fenetre fenetre = new Fenetre();
// dimensionnement de la fenêre "au plus juste" suivant
// la taille des composants qu'elle contient
fenetre.pack();
// centrage sur l'écran
fenetre.setLocationRelativeTo(null);
// affichage
fenetre.setVisible(true);

}
}






Classe ModeleDuJeu

import java.awt.Graphics;

public class ModeleDuJeu {

private Labyrinthe lelabyrinthe;
private Nourriture lanourriture;
private Personnage leperso;

public ModeleDuJeu() {

this.lelabyrinthe = new Labyrinthe();
this.lanourriture = new Nourriture();
this.leperso = new Personnage();

}

// le calcul du jeu
    public void calcul(){
    	
    	this.lelabyrinthe.calcul();
    	this.lanourriture.calcul();
    	this.leperso.calcul();
    }
    
    
    
    // le dessin graphique du jeu
    public void affichage(Graphics g) {
    	 this.lelabyrinthe.affichage(g);
    	 this.lanourriture.affichage(g);
    	 this.leperso.paintComponent(g);
    	 
    }

}


Classe Personnage :

import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;



public class Personnage extends JPanel implements Constantes {

/**
 * 
 */
private static final long serialVersionUID = 1L;
private Image img = null;
private Direction direction;
private int posX=22*CASE_EN_PIXELS, posY=23*CASE_EN_PIXELS;

public void paintComponent(Graphics g){

try {
img= ImageIO.read(new File("pac2.png"));
g.drawImage(img, posX, posY ,this);
} catch (IOException e){
e.printStackTrace();
}
this.direction = Direction.VERS_LA_GAUCHE;

}



public void personnage(int posX, int posY){
this.posX=posX;
this.posY=posY;
}

public void personnage(){
this.posX=330;	 
this.posY=345;
}

public void setPosX(int x){
if (x<=0) 
x=0;
this.posX=x;
}

public void setPosY(int y){
if (y<=0) 
y=0;
this.posY=y;
}

public int getPosX(){
return this.posX;
}
public int getPosY(){
return this.posY;
}

private void mouvement(){

for (int i= 0; i< Constantes.CASE_EN_PIXELS; i++)
{
switch (this.direction){

case VERS_LA_GAUCHE:				
this.setPosX(this.getPosX()-1);
break;
case VERS_LA_DROITE:				
this.setPosX(this.getPosX()+1);
break;
}

}
}

public void calcul() {

mouvement();
// calcul du personnage
}









}


Quelqu'un peut-il m'aider ??
Merci d'avance

12 réponses

cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
3 avril 2012 à 09:10
Bonjour
"Thread-1" java.lang.NullPointerException
at Personnage.mouvement(Personnage.java:67)

qui correspond à
switch (this.direction){


Au moment ou la fonction mouvement est appellée, direction doit être null.
Essaye de lui attribuer une valeur par défaut (par exemple dans le constructeur).


cdt
3
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 avril 2012 à 10:04
Oui tu donnes une valeur dans paintComponent, mais rien n'indique que cette méthode soit appelée avant l'appel de la fonction "mouvement". L'exception levée le prouve d'ailleurs.

Cdt
3
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 avril 2012 à 10:50
Je pense que ton initialisation de variable direction, il faut la faire dans le constructeur de ton object.
Là dans ta fonction mouvement (comme définie dans ton précédent message) ne fera pas vraiment ce que tu veux car tu passerais tout le temps dans le case "vers la gauche".
3
cs_laurent1024 Messages postés 987 Date d'inscription mardi 31 mai 2005 Statut Membre Dernière intervention 30 août 2012 25
4 avril 2012 à 11:20
Si tu veux une gestion au clavier, effectivement il faut utiliser les keylistener (ton composant doit implémenter cette interface).
dans la(les) fonction(s) de gestion de touche, tu pourra faire le test suivant :

void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
        this.direction = Direction.VERS_LA_GAUCHE;
    }
    else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
        this.direction = Direction.VERS_LA_DROITE;
    }
}
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_Julien39 Messages postés 6414 Date d'inscription mardi 8 mars 2005 Statut Modérateur Dernière intervention 29 juillet 2020 371
3 avril 2012 à 07:48
Bonjour,

A quel niveau est l'erreur ? Essaye d'isoler les parties du code qui posent problème, là, je ne vais pas tout lire...
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
3 avril 2012 à 12:22
Bonjour ,

merci de vos reponses .

@Julien l'erreur ce trouve dans le swingworker . lorsque je rentre dedans et que j'appelle la méthode mouvement , il fait la boucle puis a la fin de cette fameuse boucle , je ne retourne pas dans la classe fenêtre , je n'est plus rien qui s’affiche dans le mode debug .


@laurent : merci je regarderé ce soir et je vous tiens au courant .
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
3 avril 2012 à 12:37
j'ai oublier de preciser que dans la classe afficher , dans le swingworker , j'ai "Fenetre.this.modele.calcul();" en commentaire , il ne l'est pas normalement ( c'est moi qui l'est mis en commentaire dans le SwingWorker , et remis dans la boucle While pour avoir le message d'erreur mis en rouge .
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
4 avril 2012 à 09:50
Bonjour ,

desolé du retard .

j'ai regarder par rapport a ce que laurent m'as indiqué .
je me trompe peu etre mais la valeur de this.Direction je la donne dans la methode qui permet de d'affichre l'image . dans

"public void paintComponent(Graphics g){}" de ma classe personnage .
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
4 avril 2012 à 10:41
Exact , j'ai effectué un petit test :

J'ai mis en commentaire le "this.direction = Direction.VERS_LA_GAUCHE;" de ma méthode paintComponent() et je l'est mis dans ma méthode mouvement() comme ceci :

private void mouvement(){

this.direction = Direction.VERS_LA_GAUCHE;

for (int i= 0; i< Constantes.CASE_EN_PIXELS; i++)
{
switch (this.direction){

case VERS_LA_GAUCHE:				
 this.setPosX(this.getPosX()-1);
break;
case VERS_LA_DROITE:				
this.setPosX(this.getPosX()+1);
break;
}

}
}


Et effectivement mon image ce deplace .

Donc Pour que cela puisse fonctionné correctement , il faut que je supprime dans un premier temps mon swingworker ( qui me semble plus vraiment utile ) puis que je donne une valeur a "this.direction" dans la methode mouvement() ?
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
4 avril 2012 à 11:07
Donc dans mon cas il faudrais que j'effectue la gestion du clavier et que je mette la direction dans ma methode calcul() qui elle meme fait appel a la methode mouvement() ?



  public void calcul() {
    	this.direction = Direction.VERS_LA_GAUCHE;
    mouvement();
        // calcul du personnage
  }


desolé de poser autant de question mais il est vrai que je debute a peine et que je me sens pas vraiment à l'aise ^^.
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
4 avril 2012 à 11:32
Merci . Je vais essayer tout ceci et je reviens pour dire si tous fonctionne . Merci encore une fois de l'aide apporté .
0
djbenji81100 Messages postés 66 Date d'inscription vendredi 9 septembre 2011 Statut Membre Dernière intervention 4 juin 2012
4 avril 2012 à 16:12
Voila tous fonctionne !!!

j'ai donc géré le deplacement avec les touche du clavier et c'est parfait !!

Vous m'avez enlevé un grosse épine du pied .

Merci beaucoup

Bonne continuation

Crdt
0
Rejoignez-nous