IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

AWT/Swing Java Discussion :

repaint() n'apelle jamais paint() ou paintComponent()


Sujet :

AWT/Swing Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    764
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2008
    Messages : 764
    Par défaut repaint() n'apelle jamais paint() ou paintComponent()
    Bonjour,

    J'ai un problème de rafraîchissement du graphisme d'un panneau (PanelAffichage).

    J'ai surchargé la méthode paintComponent(g). Au lancement de l'appli, tout se dessine comme prévu. Mais lorsque j'ai besoin de faire rafraîchir le graphisme de ce PanelAffichage, j'utilise la méthode repaint() depuis une instance du PanelAffichage mais jamais la méthode paintComponent(g) n'est appelée.
    Pour vérifier, j'ai placé un system.out.println() dans la méthode paintComponent(g).
    J'ai essayé avec la méthode paint() mais c'est pareil.

    voici ma classe Controleur depuis laquelle je fait le repaint() à la ligne 90 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    package com.francky.lettres.ctrl;
     
    import java.awt.Color;
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    import java.util.Vector;
     
    import com.francky.lettres.modele.CouleurThemes;
    import com.francky.lettres.modele.Mot;
    import com.francky.lettres.modele.MotDAO;
    import com.francky.lettres.vues.FenetrePrincipale;
    import com.francky.lettres.vues.panneaux.PanelAffichage;
     
    public class Controleur {
     
    	//***********************************************************DECLARATIONS
    	FenetrePrincipale fenetreprincipale;
    	PanelAffichage panelaffichage;
    	MotDAO motdao = new MotDAO("mots.xml");
    	Vector<Mot> mots = null;		//contenant de tous les objets Mot
    	public boolean debug;			//variable pour le débuggage
    	private int randomNum;			//variable contenant le numéro trouvé par le random
    	/*
    	 * Gestion du score et des statistiques
    	 */
    	private int score;
    	private int motsTrouves;
    	private int nbreLettres;
    	private int niveau;
     
    	/*
    	 * Message d'information
    	 */
    	public String message;
     
    	/*
    	 * Gestion du mot à rechercher et à cacher
    	 */
    	private String mot;											//le mot qui a été choisi au hasard
    	private StringBuilder motCache;								//le mot transformé pour affichage
    	private ArrayList<Character> listeLettres;								//le tableau contenant toute les lettres du mot choisi au hasard
    	private List<Character> listeLettresTrouvees;				//Liste des lettres qui ont été trouvées
    	private Character lettreTrouvee;							//dernière lettre trouvée
     
    	/*
    	 * Définition de la palette des couleurs pour le jeu 
    	 */
    	private String COLOR_THEME = "theme3";	//theme1 à theme5
    	public Color COL_FOND;
    	public Color COL_TEXTE_1;
    	public Color COL_TEXTE_2;
    	public Color COL_MOT;
    	public Color COL_GRAPH;
     
    	//***********************************************************CONSTRUCTEUR
     
    	public Controleur() {
    		//************************************Initialisations
    		resetGame();
     
    		resetColors();		
     
    		choixNouveauMot();
     
    		//************************************création de la fenêtre
    		fenetreprincipale = new FenetrePrincipale(this);
     
    		fenetreprincipale.setVisible(true);
    	}
     
    	private char[] motToLettersTab(String mot2) {
    		char[] resultTab = mot.toCharArray();		
    		return resultTab;
    	}
     
    	//***********************************************************METHODES
     
    	//recherche d'une lettre cliquée dans le mot
    	public void searchLetter(Character lettreClic) {
    		for(Character lettre : mot.toCharArray()) {
    			if(lettre.equals(lettreClic)){
    														if(debug)System.out.println("lettre trouvée !");		//debug
    				message = "lettre trouvée !";
    				listeLettresTrouvees.add(lettreClic);
    				lettreTrouvee = lettreClic;
     
    				//générer et ré afficher le mot caché
    				listeLettres = setlisteLettres(listeLettres);
    				panelaffichage.repaint();
    				break;
    			} else {
    														if(debug)System.out.println("Lettre non trouvée !");	//debug
    				message = "lettre non trouvée !";
    			}
    		}
    	}
     
     
    	//Choix d'un nouveau mot parmi la liste, on retire le mot choisi de la liste,
    	//on génère le tableau de lettres du mot choisi, on génère le mot caché 
    	private void choixNouveauMot() {
     
    		randomNum = randomNum();
     
    					//affichage dans console pour debug
    					if (debug){
    						for(Mot m : mots){
    							System.out.println("mot : " + m.getChaine() + ", genre : " + m.isGenre() + ", composed : " + m.isComposed());
    						}		
    						System.out.println("randomNum = " + randomNum);
    						System.out.println("le mot est : " + mots.get(randomNum).getChaine());
    					}
     
    		mot = mots.get(randomNum).getChaine();
     
     
    		//on enleve de la liste le mot qui a été tiré au hazard pour qu'il ne soit pas choisi au hasard plusieurs fois
    		mots.remove(randomNum);
     
    					//affichage dans console pour debug
    					if (debug){
    						for(Mot m : mots){
    							System.out.println("mot : " + m.getChaine() + ", genre : " + m.isGenre() + ", composed : " + m.isComposed());
    						}		
    					}
     
    		//lorsque le nouveau mot a été choisi, il faut remplir un tableau de Character avec des underscores
    		for(int rank = 0; rank < mot.length(); rank++){
    			listeLettres.add('_');
    		}
    	}
     
    	//réinitialisation des couleurs
    	private void resetColors() {
    		//initialisation des couleurs - a l'avenir il faudra aller chercher le theme dans un .xml
    		CouleurThemes coul = new CouleurThemes(COLOR_THEME);
     
    		COL_FOND = coul.getColComplementaire_5();
    		COL_TEXTE_1 = coul.getColPrimaire_3();
    		COL_TEXTE_2 = coul.getColPrimaire_2();
    		COL_MOT = coul.getColPrimaire_3();
    		COL_GRAPH = coul.getColPrimaire_1();
    	}
     
    	//remise à zéro des paramètres d'initialisation
    	private void resetGame() {
    		debug = true;
    		setScore(0);
    		setMotsTrouves(0);
    		setNbreLettres(0);
    		setNiveau(1);
    		listeLettres = new ArrayList<Character>();
    		lettreTrouvee = ' ';
    		motCache = new StringBuilder();
    		listeLettresTrouvees = new ArrayList<Character>();
    		panelaffichage = new PanelAffichage(this);
    		mots = motdao.chargerMots();
    	}
     
    	//génération d'un entier au hasard compris entre 0 et les nombre de mots contenus dans la liste des mots en .xml
    	private int randomNum(){
    		Random rand = new Random();
    		return rand.nextInt((mots.size()));
    	}
     
    	//création du mot qui sera affiché (on montre les lettres qui ont déjà été trouvées) prend en paramètre la liste
    	private ArrayList<Character> setlisteLettres(ArrayList<Character> listeLettres){	
    		for (int rank = 0; rank < listeLettres.size(); rank++){
    			if(listeLettres.get(rank).equals('_')){
    				if(lettreTrouvee.equals(mot.charAt(rank))){
    					listeLettres.set(rank, lettreTrouvee);
    				}
    			}
    		}		
     
    		return listeLettres;
    	}
    	//***********************************************************GETTERS & SETTERS
    	public int getScore() {return score;}
    	public void setScore(int score) {this.score = score;}
     
    	public int getMotsTrouves() {return motsTrouves;}
    	public void setMotsTrouves(int motsTrouves) {this.motsTrouves = motsTrouves;}
     
    	public int getNbreLettres() {return nbreLettres;}
    	public void setNbreLettres(int nbreLettres) {this.nbreLettres = nbreLettres;}
     
    	public int getNiveau() {return niveau;}
    	public void setNiveau(int niveau) {this.niveau = niveau;}
     
    	public String getMot() {return mot;}
    	public void setMot(String mot) {this.mot = mot;}
     
    	public List<Character> getListeLettres() {return listeLettres;}
    }
    voici le panneau PanelAffichage avec la méthode paintComponent à la ligne 55 :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    package com.francky.lettres.vues.panneaux;
     
    import java.awt.Dimension;
    import java.awt.Font;
    import java.awt.Graphics;
     
    import javax.swing.JPanel;
     
    import com.francky.lettres.ctrl.Controleur;
     
    public class PanelAffichage extends JPanel {
     
    	/**
             * 
             */
    	private static final long serialVersionUID = 8624942466374820397L;
     
    	//***********************************************************DECLARATIONS
    	private Controleur ctrl;
    	int x = 0;
    	/*
    	 * Taille du panneau affichage
    	 */
    	private static final int PANEL_WIDTH = PanelKeyboard.KEYBOARD_WIDTH + PanelScore.SCORE_WIDTH;
    	private static final int PANEL_HEIGHT = 150;
     
    	/*
    	 * Taille et position de la zone d'affichage du texte
    	 */
    	private static final int TEXT_ZONE_WIDTH = PanelKeyboard.KEYBOARD_WIDTH + PanelScore.SCORE_WIDTH - 20;
    	private static final int TEXT_ZONE_HEIGHT = 100;
    	private static final int TEXT_ZONE_X = 10;
    	private static final int TEXT_ZONE_Y = 25;
     
    	/*
    	 * Taille et position du mot à chercher
    	 */
    	private static final int MOT_TAILLE = 50;
    	private static final Font MOT_FONT = new Font("Tahoma", Font.BOLD, MOT_TAILLE);
    	private static final int MOT_Y = TEXT_ZONE_HEIGHT / 2 + TEXT_ZONE_Y + 20;
    	private static final int MOT_X = TEXT_ZONE_X + 15;
     
    	//***********************************************************CONSTRUCTEUR
    	public PanelAffichage(Controleur ctrl) {
    		this.ctrl = ctrl;
     
    		setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
    		setBackground(ctrl.COL_FOND);
    	}
    	//***********************************************************GETTERS & SETTERS
     
     
    	//***********************************************************METHODES
    	@Override
    	public void paintComponent(Graphics g) {
    		super.paintComponent(g);
     
    		g.setColor(ctrl.COL_GRAPH);
    		g.drawRect(TEXT_ZONE_X, TEXT_ZONE_Y, TEXT_ZONE_WIDTH, TEXT_ZONE_HEIGHT);
     
    		//affichage du mot caché
    		g.setColor(ctrl.COL_MOT);
    		g.setFont(MOT_FONT);
    		int decal = 0;
     
    		for(int caractere = 0; caractere < ctrl.getListeLettres().size(); caractere++){
    			g.drawString("" + ctrl.getListeLettres().get(caractere), MOT_X + decal, MOT_Y);
    			System.out.println("paint is called");
    			decal += 45;
    		}
    	}
    }
    et voici ma classe FenetrePrincipale à partir de laquelle je créé mon PanelAffichage :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    package com.francky.lettres.vues;
     
    import java.awt.BorderLayout;
     
    import javax.swing.JFrame;
     
    import com.francky.lettres.ctrl.Controleur;
    import com.francky.lettres.vues.panneaux.PanelAffichage;
    import com.francky.lettres.vues.panneaux.PanelKeyboard;
    import com.francky.lettres.vues.panneaux.PanelScore;
     
    public class FenetrePrincipale extends JFrame {
     
    	/**
             * 
             */
    	private static final long serialVersionUID = -221472257022120727L;
     
    	//********************************************************DECLARATIONS
    	private Controleur ctrl;
     
    	public FenetrePrincipale(Controleur ctrl) {
    		//construction de la fenêtre
    		super("Lettres");
    		setLayout(new BorderLayout());
    		setDefaultCloseOperation(EXIT_ON_CLOSE);
    		setResizable(false);
     
    		this.ctrl = ctrl;
     
    		/*
    		 * Initialisation des panneaux
    		 */
    		//création du clavier
    		PanelKeyboard panelkeyboard = new PanelKeyboard(ctrl);
    		//ajout du clavier à la fenêtre
    		add(panelkeyboard, BorderLayout.CENTER);
     
    		//Création du panneau de score
    		PanelScore panelscore = new PanelScore(ctrl);
    		add(panelscore, BorderLayout.EAST);
     
    		//création du panneau d'affichage des mots
    		PanelAffichage panelaffichage = new PanelAffichage(ctrl);
    		add(panelaffichage, BorderLayout.NORTH);
     
    		pack();
    		setLocationRelativeTo(null);
    	}
    }
    Si quelqu'un veut bien m'aider, je vous en remercie bien par avance !


  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    764
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2008
    Messages : 764
    Par défaut
    Bonjour,

    J'ai remarqué que si, dans le PanelAffichage, je remplace dans la méthode paintComponent le super.paintCoponent(g) par un super.repaint(), j'obtiens un rafraîchissement constant. Mais cela n'arrange rien car on ne voit pas le graphisme qui est constament renouvelé ... donc j'ai remis le super.paintComponent(g) à sa place dans PanelAffichage.

    Par contre, j'ai remplacé, dans le Controleur, le panelaffichage.repaint() par ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    fenetreprincipale.setVisible(false);
    fenetreprincipale.setVisible(true);
    cela fait disparaitre et réapparaître aussitôt ma fenêtre et donc appelle paintComponent .... l'effet n'est pas génial car cela fait comme un effet de tremblement de la la fenêtre mais je n'ai que cela pour l'instant.


  3. #3
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    764
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2008
    Messages : 764
    Par défaut euréka !!!
    Bon ben voilà ... après avoir écris le message précédent, je me suis dit :
    puisqu'en faisant disparaitre et ré-apparaître la fenêtre ça force le repaint .... peut-être ma fenetreprincipale possède elle aussi un repaint component ????

    Et c'est ça en fait !

    Il fallait rafraîchir la fenêtre principale sur laquelle est posé le panelaffichage !

    donc voici :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    fenetreprincipale.repaint();

  4. #4
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 56
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Billets dans le blog
    2
    Par défaut
    Salut,

    Normalement, il suffit d'appeler repaint() sur le composant qu'on veut repeindre. Forcément, si on fait le repaint() sur un de ses parents, comme la fenêtre qui le contient, ça va repeindre le composant, mais aussi plein de choses qui n'ont pas besoin de l'être.

    Ça ne fonctionne pas dans ton programme parce que :

    • tu appelles repaint() sur un panel qui est référencé par une variable, mais ce n'est pas ce panel qui est affiché dans la fenêtre
    • celui qui est dans la fenêtre est celui créé ici :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      PanelAffichage panelaffichage = new PanelAffichage(ctrl);
      		add(panelaffichage, BorderLayout.NORTH);
      code qui se trouve dans le constructeur de FenetrePrincipale
    • alors que le repaint est fait sur l'instance qui est stockée dans la variable panelaffichage de la classe Controleur
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      public class Controleur {
       
      	//***********************************************************DECLARATIONS
      	FenetrePrincipale fenetreprincipale;
      	PanelAffichage panelaffichage;
      Cette variable contient l'instance qui est créée dans la méthode resetGame :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      private void resetGame() {
                      /* ... */
      		panelaffichage = new PanelAffichage(this);
      		/*...*/
      	}
      Et ce panel n'est jamais mis dans aucun conteneur, donc ne sera jamais affiché


    Ce serait plus simple que la fenêtre créé le Controleur, en lui passant l'instance de PanelAffichage à la construction. Au reset, au lieu de récréer un PanelAffichage, tu le vides, et là tu fais un revalidate() puis un repaint() (sur panelAffichage) (sinon, il te faut une référence sur la FenetreAffichage, enlever le précédent, et mettre le nouveau à la place...).
    En général, un controlleur est tellement dédié à une vue, qu'il est inutile que cela soit une classe externe : une classe interne qui a accès à l'ensemble des composants de la vue est beaucoup plus pratique à utiliser. Tu peux faire un controlleur abstrait externe avec des comportements génériques, que tu veux pouvoir utiliser dans plusieurs vues.


    Par ailleurs :

    Citation Envoyé par francky74 Voir le message
    J'ai remarqué que si, dans le PanelAffichage, je remplace dans la méthode paintComponent le super.paintCoponent(g) par un super.repaint(), j'obtiens un rafraîchissement constant. Mais cela n'arrange rien car on ne voit pas le graphisme qui est constament renouvelé ... donc j'ai remis le
    Tu l'as vu : ne jamais appeler repaint() dans paint(), paintComponent() etc... repaint() déclenche des appels à paint(), donc tu crées une boucle de rafraichissement (repaint() appel paint() qui appelle repaint() qui appelle paint() etc.) continue (comme tu as pu le constater).
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  5. #5
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2008
    Messages
    764
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Février 2008
    Messages : 764
    Par défaut
    Bonjour Joel,

    Merci beaucoup pour vos réponses expertes très intéressantes !

    J'ai bien compris les erreurs que j'ai faites avec les instances. Au lieu de créer plusieurs instances dans plusieurs classes, il vaut mieux en créer une seule et la passer en argument aux classes qui vont devoir s'en servir !

    Merci

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [JPanel] paint, paintComponent et repaint ?
    Par Pill_S dans le forum Composants
    Réponses: 8
    Dernier message: 08/02/2013, 18h38
  2. Entre Paint et PaintComponent y a un truc que je pige pas?
    Par doul21 dans le forum Débuter avec Java
    Réponses: 6
    Dernier message: 11/04/2008, 11h17
  3. paint ou paintComponents ?
    Par g0up1l dans le forum AWT/Swing
    Réponses: 7
    Dernier message: 19/05/2007, 23h15
  4. methode paint jamais appeller.
    Par Blo0d4x3 dans le forum 2D
    Réponses: 9
    Dernier message: 22/01/2006, 23h44
  5. [JScrollPane][paint] pas de repaint
    Par wonderyan dans le forum AWT/Swing
    Réponses: 15
    Dernier message: 17/01/2006, 12h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo