Partage
  • Partager sur Facebook
  • Partager sur Twitter

paintComponent ne répond pas à l'appel de repaint

repaint appelle-t-il dans tous les cas paintComponent ?

Sujet résolu
    19 juin 2009 à 22:08:48

    Bonjour,

    J'ai créé un projet où on utilise repaint() dans une méthode appelée par une implémentation de KeyListener et je me rends compte que repaint() n'appelle pas toujours paintCompononent() :waw: . J'ai créé un projet beaucoup plus simple pour expliquer mon problème (il est en trois classes) :
    -Voici mon Main :
    public class Main {
    
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		
    		Fenetre fenetre = new Fenetre();
    	}
    }
    

    -Voici ma Fenetre :
    public class Fenetre extends JFrame {
    	
    	private static Panneau panneau = new Panneau();
    	
    	public Fenetre(){
    		
    		this.setTitle("Fenêtre Basique");
    		this.setSize(600,400);
    		this.setContentPane(panneau);
    		this.setLocationRelativeTo(null);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		System.out.println("Essai de 1er repaint");
    		panneau.repaint();
    		System.out.println("Fin du premier essai");
    		methodeAppelant();
    	}
    	public static void methodeAppelant(){
    		
    		System.out.println("Essai de 2ème repaint");
    		panneau.repaint();
    		System.out.println("Fin du deuxième essai");
    	}
    }
    

    -Et voici mon Panneau :
    import java.awt.Graphics;
    
    import javax.swing.JPanel;
    
    
    public class Panneau extends JPanel {
    
    	public void paintComponent(Graphics g){
    		
    		System.out.println("repaint");
    	}
    }
    

    Et là, d'abord la console affiche les quatres affichages de ma Fenetre, puis deux repaint d'affilée.
    Je n'y comprend plus rien ! Par pitié, aidez-moi !

    Merci :)
    • Partager sur Facebook
    • Partager sur Twitter
      19 juin 2009 à 22:29:22

      Non non ça marche très bien ;)

      Le fait est que repaint() ne s'occupe pas de repeindre comme son nom l'indique, mais de poster des instructions dans l'Event Dispatch Thread qui elles seront exécutées à un certain moment (que tu ne peux pas contrôler de cette manière).

      Et donc tu vois que toutes les instructions s'exécutent et que le paintComponent a fini de s'exécuter à la fin seulement. C'est un comportement normal.

      • Partager sur Facebook
      • Partager sur Twitter
        20 juin 2009 à 8:34:19

        Merci, en réfléchissant, je pense que j'ai trouvé le moyen de résoudre le problème avec mon programme. :ange:
        Parce qu'en fait j'avais une classe implémentée de KeyListener avec trois touches surveillées avec keyPressed() et keyReleased(). keyPressed() appelait une méthode dans laquelle je vérifiais qu'aucune touche n'avait été relachée. Ca n'avait pas de sens puisque j'utilisais justement la pile de ma classe ClavierListener (la classe implémentée)...

        Voilà, si quelqu'un voit une faute dans ce que je viens de dire, ce serait gentil, ce serait gentil de le dire. :honte:

        Mais... ce serait quand même bien si quelqu'un pouvait me dire comment obliger d'actualiser mon panneau tout de suite (ou d'attendre le résultat) car ça peut poser de sérieux problèmes à ma fluidité si mon rectangle (c'est mon projet) ne s'affiche que quand il est arrivé au bout de la fenêtre... :p

        Merci
        • Partager sur Facebook
        • Partager sur Twitter
          21 juin 2009 à 11:15:50

          Avec une boucle ?

          boolean laToucheAappuyee=false;
          boolean laToucheBappuyee=false;
          
          boolean onRepaint=true;
          int tempsEnMilliSecondes=10;
          while(onRepaint){
          
          panneau.repaint();
          Thread.sleeep(tempsEnMilliSecondes);
          
          if (laToucheAappuyee){//et là tu executes ce que tu veux}
          if (laToucheBappuyee){//et là tu executes ce que tu veux}
          }
          


          (avec une capture d'exeptions sur le Thread.sleep(); )

          En gros tu met a true laToucheAappuyee dans le KeyPressed;
          A false dans le KeyReleased

          <Pas testé>
          • Partager sur Facebook
          • Partager sur Twitter
            21 juin 2009 à 19:04:35

            Salut Lanube,

            Effectivement, c'est avec un boucle et une petite pause entre...

            J'ai une classe héritée de KeyAdapter avec les méthodes keyPressed() et keyReleased() qui surveillent trois touches : gauche, droite et haut. Là, à l'intérieur , je change effectivement l'état de mes booléens droite, gauche et haut qui voient si la touche est enfoncée. Dans keyPressed(), je vérifie si les touches n'étaient pas déjà auparavant enfoncées, et si c'est le cas, j'appelle ma méthode bouger(). Celle-ci vérifie si c'est à partir de gauche, droite ou haut qu'elle a été appelée (avec des booléens bougerDroite, bougerGauche et bougerHaut qui sont transformés en true dans le ClavierListener et directement retransformés en true après la vérification dans le cœur de ma méthode bouger() (ou les trois cœurs), j'ai une boucle qui vérifie si (dans le cas de la droite) droite vaut toujours true, gauche vaut toujours false (quand droite et gauche sont enfoncés, le rectangle que je bouge reste immobile) et qu'on n'est pas trop près du bord de la fenêtre. Ensuite dans cette boucle, il y a un autre boucle (for) qui réalise le mouvement en lui-même , dont les actions sont d'incrémenter une variable publique positionX, de faire une petite pause et ensuite (essayer de ;) ) repeindre mon panneau pour faire bouger ce maudit rectangle... :p

            Voici mes classes :

            -mon Main :
            public class MainMouvementsDeBaseFetoua {
            	
            	public static void main(String[] args) {
            		
            		Fenetre fenetre = new Fenetre();
            	}
            }
            

            -ma Fenetre :
            import java.awt.event.KeyAdapter;
            import java.awt.event.KeyEvent;
            
            import javax.swing.JFrame;
            
            
            public class Fenetre extends JFrame {
            	
            	private static Panneau panneau;
            	private static boolean gauche = false, droite = false, haut = false, bougerDroite = false, bougerGauche = false, bougerHaut = false;
            	public static int positionX, positionY;
            	public static final double COS_30 = Math.cos(Math.toRadians(30));
            	
            	public Fenetre(){
            		
            		this.setTitle("Mouvements de base de Fétoua");
            		this.setSize(600,200);
            		this.setResizable(false);
            		panneau = new Panneau();
            		this.setContentPane(panneau);
            		this.setLocationRelativeTo(null);
            		this.addKeyListener(new ClavierListener());
            		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            		this.setVisible(true);
            		positionX = 0;
            		positionY = panneau.getHeight() - 50;
            	}
            	public static void bouger(){
            				
            		if(droite && bougerDroite){
            			
            			bougerDroite = false;
            			
            			while(droite && !gauche && positionX < panneau.getWidth() - 25){
            								
            				for(int i = 0; i < 25; i++){
            					try{
            						Thread.sleep(20);
            					}catch(InterruptedException ie){
            						ie.printStackTrace();
            					}
            					positionX++;
            					panneau.repaint();
            				}
            			}
            		}
            		else if(gauche && bougerGauche){
            			
            			bougerGauche = false;
            			
            			while(gauche && !droite && positionX <= 50){
            				for(int i = 0; i < 25; i++){
            					
            					try{
            						Thread.sleep(20);
            					}catch(InterruptedException ie){
            						ie.printStackTrace();
            					}
            					positionX--;
            					panneau.repaint();
            				}
            			}
            		}
            		else if(haut && bougerHaut){
            			
            			bougerHaut = false;
            			
            			do{
            				int positionInitialeY = positionY, hauteurSaut;
            				
            				for(int i = 0; i < (int) (75 * COS_30); i++){
            					
            					try{
            						Thread.sleep(10);
            					}catch(InterruptedException ie){
            						ie.printStackTrace();
            					}
            					hauteurSaut = (int) ((Math.sin(Math.acos((double) (i) / 75 - COS_30)))- 0.5) * 200;
            					positionY = positionInitialeY - hauteurSaut;
            					panneau.repaint();
            				}
            			}while(haut);
            		}
            	}
            	class ClavierListener extends KeyAdapter{
            		
            		public void keyPressed(KeyEvent ke){
            						
            			if(ke.getKeyCode() == 39 && !droite){
            								
            				droite = true;
            				
            				if(!gauche){
            					
            					bougerDroite = true;
            					bouger();
            				}
            			}
            			else if(ke.getKeyCode() == 37 && !gauche){
            				
            				gauche = true;
            				if(!droite){
            					
            					bougerGauche = true;
            					bouger();
            				}
            			}
            			else if(ke.getKeyCode() == 38 && !haut){
            				
            				haut = true;
            				bougerHaut = true;
            				bouger();
            			}
            		}
            		public void keyReleased(KeyEvent ke){
            			
            			if(ke.getKeyCode() == 39)
            				droite = false;
            			else if(ke.getKeyCode() == 37)
            				gauche = false;
            			else if(ke.getKeyCode() == 38)
            				haut = false;
            		}
            	}
            }
            

            -et mon Panneau
            import java.awt.Color;
            import java.awt.Graphics;
            
            import javax.swing.JPanel;
            
            
            public class Panneau extends JPanel {
            	
            	public void paintComponent(Graphics g){
            		
            		g.setColor(Color.WHITE);
            		g.fillRect(0, 0, this.getWidth(), this.getHeight());
            		g.setColor(Color.BLUE);
            		g.fillRect(Fenetre.positionX, Fenetre.positionY, 25, 50);
            	}
            }
            

            (désolé, ce n'est pas commenté, mais j'ai déjà expliqué un peu au-dessus, et aussi petite remarque : la formule pour la hauteur est une formule alchimique mathématique compliquée pour avoir un quart de cercle deux fois plus haut dans le mouvement saut + droite)

            Le problème est que paintComponent() et keyReleased() attendent bêtement que le rectangle soit arrivé au bout de la fenêtre pour s'exécuter :colere:

            Bon, merci de porter tant d'attention à mon problème, j'en ai vraiment besoin (c'est quand même la base pour créer un jeu !

            P.S.(petite supposition): j'ai l'impression que ces deux méthodes attendent que je sois sorti de ma méthode bouger pour s'exécuter... >_<

            Au revoir !
            • Partager sur Facebook
            • Partager sur Twitter
              22 juin 2009 à 16:13:05

              La classe Main

              public class MainMouvementsDeBaseFetoua {
              
              	/**
              	 * @autor Lanube
              	 */
              	public static void main(String[] args) {
              		Fenetre fenetre = new Fenetre(600,300,"Lanube");
              
              	}
              
              }
              



              Et la classe Fenetre:
              import java.awt.Color;
              import java.awt.Graphics;
              import java.awt.event.KeyAdapter;
              import java.awt.event.KeyEvent;
              import javax.swing.JFrame;
              import javax.swing.JPanel;
              
              class Fenetre extends JFrame {
              	
              	boolean gauche = false, droite = false, haut = false,bas=false;
              	int positionX, positionY;
              	
              	
              	Panneau panneau = new Panneau();
              	
              	Fenetre(int largeur,int hauteur,String titre){
              		
              		this.setTitle(titre);
              		this.setSize(largeur,hauteur);
              		this.setResizable(false);
              		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              		this.setLocationRelativeTo(null);
              		this.addKeyListener(new ClavierListener());
              		this.setContentPane(panneau);	
              		this.setVisible(true);
              		
              		bougerOuPas();
              
              	}
              	void bougerOuPas(){
              				
              		for(;;){
              			//Une pause toute les 10 millisecondes
              			try {
              				Thread.sleep(10);
              			} catch (InterruptedException e) {
              				e.printStackTrace();}
              			
              			//On repaint
              			panneau.repaint();
              			
              			if(gauche)positionX--;
              			if(droite)positionX++;
              			if(haut)positionY--;
              			if(bas)positionY++;
              		}
              	}
              	
              	class ClavierListener extends KeyAdapter{
              		        public void keyPressed(KeyEvent ke) {  
              		        	switch(ke.getKeyCode()){
              		        	case KeyEvent.VK_DOWN:
              		        		bas=true;
              		        		break;
              		        	case KeyEvent.VK_UP:
              		        		haut=true;
              		        		break;
              		        	case KeyEvent.VK_LEFT:
              		        		gauche=true;
              		        		break;
              		        	case KeyEvent.VK_RIGHT:
              		        		droite=true;
              		        		break;
              		        	}                
              		}
              		public void keyReleased(KeyEvent ke){
              			switch(ke.getKeyCode()){
                      	case KeyEvent.VK_DOWN:
                      				bas=false;
                      				break;
                      	case KeyEvent.VK_UP:
                      				haut=false;
                      				break;
                      	case KeyEvent.VK_LEFT:
                      				gauche=false;
                      				break;
                      	case KeyEvent.VK_RIGHT:
                      				droite=false;
                      				break;			
              			}
              		}
              	}
              	public class Panneau extends JPanel {
              		
              		protected void paintComponent(Graphics g){
              			
              			g.setColor(Color.WHITE);
              			g.fillRect(0, 0, this.getWidth(), this.getHeight());
              			g.setColor(Color.BLUE);
              			g.fillRect(positionX, positionY, 25, 50);
              		}
              	}
              }
              


              Après je n'ai pas vraiment compris ce que tu voulais faire avec ton sinus, et je n'ai pas limité ton rectangle aux bords de ta fenetre.... :-°





              • Partager sur Facebook
              • Partager sur Twitter
                22 juin 2009 à 18:20:39

                Merci infiniment, Lanube !

                Je suis aux anges... :ange:;)
                Ca marche, je vais pouvoir continuer mon projet ! :magicien:
                Je m'y mets tout de suite... :)

                Merci encore !
                • Partager sur Facebook
                • Partager sur Twitter

                paintComponent ne répond pas à l'appel de repaint

                × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                • Editeur
                • Markdown