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

Agents de placement/Fenêtres Java Discussion :

Problème avec la méthode repaint()


Sujet :

Agents de placement/Fenêtres Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 4
    Par défaut Problème avec la méthode repaint()
    Bonjour, je suis en train de programmer un programme qui joue au morpion contre un utilisateur et j'ai un problème d'affichage quand l'ordinateur joue un coup. Voici la fonction qui s'execute quand l'utlisateur joue un coup :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void faireJouerOrdi() {
    		Grille.nbTurn++;
    		Grille=Fonction.choice(Grille); 
    		Grille.printG();
    		Grille.repaint();
    	}

    --Grille est l'instance de ma classe Grid qui étend JPanel et qui contient les informations sur l'état du jeu à un moment donné.
    --La fonction choice renvoie la nouvelle grille de jeu à afficher après que le programme a décidé de son coup.
    --La méthode printG de ma classe Grid me permet d'afficher la grille dans la console renvoyée par la fonction choice après que l'ordinateur a joué son coup. (Pour vérifier les calculs du programme puisqu'ils ne s'affichent pas dans la fenêtre prévue)
    --La surcharge de paintComponents dans Grid est composée de trois méthodes de Grid :
    une pour dessiner le plateau de jeu;
    une pour dessiner les ronds;
    une pour dessiner les croix;
    --La methode faireJouerOrdi() est écrite dans une classe Buttons qui étend aussi JPanel. (Les instance de Buttons ont un attribtut Grid)

    Le problème est que seul le plateau de jeu s'affiche dans la fenêtre contenant le panel. Encore plus curieux, quand je met la troisième ligne en commentaire..... :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    public void faireJouerOrdi() {
    		Grille.nbTurn++;
    		//Grille=Fonction.choice(Grille);
    		Grille.printG();
    		Grille.repaint();
    	}
    ....le panel s'affiche correctement dans la fenêtre( c-à-d les coups de l'utilisateur s'affichent ) mais alors l'ordinateur ne joue plus puisque c'est la fonction Fonction.choix qui met à jour l'état du jeu après le coup de l'ordinateur. J'ai l'impression que repaint() ne s'éxecute pas après la fonction Fonction.choice. Est-ce que quelqu'un saurait pourquoi ? Merci d'avance pour votre aide, en espérant avoir été clair.

  2. #2
    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,

    Difficile de te répondre sans avoir plus de code. Ton problème est probablement lié à un problème de thread et Event Dispatch Thread (l'EDT).
    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.

  3. #3
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 4
    Par défaut
    Salut et merci pour ta réponse. Voila le code de ma classe Grid et de ma classe Boutons :
    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
     
    public class Grid extends JPanel {
    	public Player[][] state;// le type Player est une enumeration (EMPTY, DOT, CROSS). Le tableau state est la représentation du plateau de jeu (3x3)
    	int nbTurn = 0;
     
    	public Grid() {
    		setBackground(Color.BLACK);
    		setPreferredSize(new Dimension(300, 300));
    		state = new Player[3][3];// toutes les cases de state sont mises a Player.EMPTY.
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				state[i][j] = Player.EMPTY;
    			}
    		}
    	}
     
    	public void drawGrid(Graphics g) { // dessine le plateau de jeu (#)
    		g.setColor(Color.WHITE);
    		g.fillRect(95, 0, 10, 300);
    		g.fillRect(195, 0, 10, 300);
    		g.fillRect(0, 95, 300, 10);
    		g.fillRect(0, 195, 300, 10);
    	}
     
    	public void drawDot(Graphics g, int i, int j) {// la grille de jeu et représentée par un tableau 3x3. drawDot() trace un point en position (i,j).
    		if (state[i][j].equals(Player.DOT)) {
    			g.setColor(Color.WHITE);
    			int xShift=j * 100;
    			int yShift=i*100;
    			g.fillOval( xShift+ 5, yShift + 5, 85, 85);
    		}
    	}
     
    	public void drawCross(Graphics g, int i, int j) {//trace une croix en position (i,j).
    		if (state[i][j].equals(Player.CROSS)) {
    			g.setColor(Color.WHITE);
    			int xShift = j * 100;
    			int yShift = i * 100;
    			int[] xPoints = { 20 + xShift, 15 + xShift, 85 + xShift, 90 + xShift, 20 + xShift };
    			int[] yPoints = { 15 + yShift, 20 + yShift, 90 + yShift, 85 + yShift, 15 + yShift };
    			g.fillPolygon(xPoints, yPoints, 5);
    			int[] sPoints = { 15 + xShift, 20 + xShift, 90 + xShift, 85 + xShift, 15 + xShift };
    			int[] tPoints = { 85 + yShift, 90 + yShift, 20 + yShift, 15 + yShift, 85 + yShift };
    			g.fillPolygon(sPoints, tPoints, 5);
     
    		}
    	}
     
     
    	public void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		drawGrid(g);
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				drawDot(g, i, j);
    				drawCross(g, i, j);
    			}
    		}
    	}
     
    	public int eval() { // teste à chaque tour si il y a un gagant; retourne 1 si le joueur gagne, -1 si l'ordi gagne, 0 sinon.
    		   if (nbTurn < 5) {
    			return 0;
    		}
    		for (int i = 0; i < 3; i++) {
    			if (state[i][0].equals(state[i][1]) && state[i][0].equals(state[i][2]) && state[i][0].equals(Player.DOT)) {
    				return -1;
    			}
    			if (state[i][0].equals(state[i][1]) && state[i][0].equals(state[i][2]) && state[i][0].equals(Player.CROSS)) {
    				return 1;
    			}
    		}
    		for (int j = 0; j < 3; j++) {
    			if (state[0][j].equals(state[1][j]) && state[0][j].equals(state[2][j]) && state[0][j].equals(Player.DOT)) {
    				return -1;
    			}
    			if (state[0][j].equals(state[1][j]) && state[0][j].equals(state[2][j]) && state[0][j].equals(Player.CROSS)) {
    				return 1;
    			}
    		}
    		if (state[0][0].equals(state[2][2]) && state[0][0].equals(state[1][1]) && state[0][0].equals(Player.DOT)) {
    			return -1;
    		}
    		if (state[0][0].equals(state[2][2]) && state[0][0].equals(state[1][1]) && state[0][0].equals(Player.CROSS)) {
    			return 1;
    		}
    		if (state[0][2].equals(state[2][0]) && state[0][2].equals(state[1][1]) && state[0][2].equals(Player.DOT)) {
    			return -1;
    		}
    		if (state[0][2].equals(state[2][0]) && state[0][2].equals(state[1][1]) && state[0][2].equals(Player.CROSS)) {
    			return 1;
    		}
     
    		return 0;
    	}
     
    	public void printG() {
    		for (int i = 0; i < 3; i++) {
    			System.out.println(state[i][0].toString() + state[i][1].toString() + state[i][2].toString());
     
    		}
    	}
     
    	public Grid makeCopy() {
    		Grid copyOf = new Grid();
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				copyOf.state[i][j] = state[i][j];
    			}
    			copyOf.nbTurn = nbTurn;
     
    		}
    		return copyOf;
    	}
     
    }
    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
     
    public class Boutons extends JPanel implements ActionListener {
     
    	private static final long serialVersionUID = 1;
    	private JButton UN = new JButton("1");
    	private JButton DEUX = new JButton("2");
    	private JButton TROIS = new JButton("3");
    	private JButton QUATRE = new JButton("4");
    	private JButton CINQ = new JButton("5");
    	private JButton SIX = new JButton("6");
    	private JButton SEPT = new JButton("7");
    	private JButton HUIT = new JButton("8");
    	private JButton NEUF = new JButton("9");
    	public Grid Grille = new Grid();
     
    	public Boutons() {
    		setLayout(new FlowLayout());
    		JPanel touches = new JPanel();
    		touches.setLayout(new GridLayout(3, 3));
    		touches.add(UN);
    		touches.add(DEUX);
    		touches.add(TROIS);
    		touches.add(QUATRE);
    		touches.add(CINQ);
    		touches.add(SIX);
    		touches.add(SEPT);
    		touches.add(HUIT);
    		touches.add(NEUF);
    		add(touches);
    		add(Grille);
    		UN.addActionListener(this);
    		DEUX.addActionListener(this);
    		TROIS.addActionListener(this);
    		QUATRE.addActionListener(this);
    		CINQ.addActionListener(this);
    		SIX.addActionListener(this);
    		SEPT.addActionListener(this);
    		HUIT.addActionListener(this);
    		NEUF.addActionListener(this);
    	}
     
    	public void actionPerformed(ActionEvent e) { /* Pour chaque bouton, met à jour l'attribut Grille de this avec une croix (Player.CROSS) à l'endroit correspondant puis éxécution de la fonction faireJouerOrdi();*/
     
    		if (e.getSource() == UN && Grille.state[0][0].equals(Player.EMPTY)) {
    			Grille.state[0][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
     		if (e.getSource() == DEUX && Grille.state[0][1].equals(Player.EMPTY)) {
    			Grille.state[0][1] = Player.CROSS;
    			faireJouerOrdi();
    		}
     		if (e.getSource() == TROIS && Grille.state[0][2].equals(Player.EMPTY)) {
    			Grille.state[0][2] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == QUATRE && Grille.state[1][0].equals(Player.EMPTY)) {
    			Grille.state[1][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		 if (e.getSource() == CINQ && Grille.state[1][1].equals(Player.EMPTY)) {
    			Grille.state[1][1] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == SIX && Grille.state[1][2].equals(Player.EMPTY)) {
    			Grille.state[1][2] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == SEPT && Grille.state[2][0].equals(Player.EMPTY)) {
    			Grille.state[2][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == HUIT && Grille.state[2][1].equals(Player.EMPTY)) {
    			Grille.state[2][1] = Player.CROSS;
    			faireJouerOrdi();
    		}
     		if (e.getSource() == NEUF && Grille.state[2][2].equals(Player.EMPTY)) {
    			Grille.state[2][2] = Player.CROSS;
    			faireJouerOrdi();
    		}
    	}
     
    	public void faireJouerOrdi(); {
    		Grille.nbTurn++; // important pour la fonction Fonction.choice.
     		Grille=Fonction.choice(Grille); // choisi le prochain coup de l'ordi à partir du plateau de jeu après le coup du joueur.
    		Grille.printG();
    		Grille.repaint();// affiche le coup du joueur et le coup de l'ordi en même temps.
    	}
    }
    Et le main :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    public static void main(String[] args) {
     
    		JFrame win = new javax.swing.JFrame("Morpion");
    		Boutons Buttons = new Boutons();
    		win.setResizable(true);
    		win.setContentPane(Buttons);
    		win.setLocationRelativeTo(null);
    		win.setVisible(true);
    		win.pack();
    		win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    	}
    C'est peut-être pas très bien fait ou pas très lisible, c'est la première fois que je programme quelque chose d'aussi gros et avec une interface graphique. Je n'ai pas utilisé de Event Dispatch Thread pour les boutons (j'ai recopié le premier truc que j'ai trouvé pour faire des boutons) je devrais ? Merci d'avance

  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
    Citation Envoyé par wouter Voir le message
    Je n'ai pas utilisé de Event Dispatch Thread pour les boutons
    Ce thread est forcément utilisé par Swing, pour afficher comme pour traiter les réactions aux évènements d'ActionListener, entre autres.
    Un thread ne pouvant faire qu'une seule chose à fois, tant qu'il exécute du code, aucun affichage ne peut être visible ni aucune interaction ne peut être faite. Par exemple, avec un ActionListener, l'application est gelée, jusqu'à la fin de l'exécution de la méthode actionPerformed. Tu peux faire autant de repaint que tu veux, tu n'en verras le résultat qu'à la fin de l'exécution. Si l'exécution est courte, tout semble se dérouler normalement, mais si l'exécution est longue, l'application semble figée, et on aura aucun affichage intermédiaire. En particulier, avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void faireJouerOrdi(); {
    		Grille.nbTurn++; // important pour la fonction Fonction.choice.
    		Grille=Fonction.choice(Grille); // choisi le prochain coup de l'ordi à partir du plateau de jeu après le coup du joueur.
    		Grille.printG();
    		Grille.repaint();// affiche le coup du joueur et le coup de l'ordi en même temps.
    	}
    Comme on appelle cette méthode juste après que l'utilisateur est fait son choix en cliquant sur l'un des boutons, son choix ne pourra être visible que lorsque cette méthode sera terminée, et surtout si elle se termine correctement de manière à ce que Grille.repaint() soit bien exécuté.

    N'ayant pas le code Fonction.choice(Grid), je ne peux faire que des suppositions.

    La première chose que je peux supposer et que cette méthode ne fait appel à aucun thread en particulier (ne lance pas sa tâche via un SwingWorker par exemple). Ce qui veut dire que tout le code qu'elle exécute de fait dans l'Event Dispatch Thread. Et donc tant qu'elle s'exécute, l'application est figée. Pas de mise à jour de l'affichage, pas de réaction des boutons...

    Si cette méthode plante en faisant une exception, tu devrais à priori voir une stacktrace en console. Si ce n'est pas le cas, peut-être est-ce une boucle infinie, et donc Grille.repaint() n'est jamais exécuté.

    Est-ce que tu vois toujours la trace provoquée par l'appel de Grille.printG() ?

    Enfin, il y a ça qui m'interpelle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public Grid makeCopy() {
    		Grid copyOf = new Grid();
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				copyOf.state[i][j] = state[i][j];
    			}
    			copyOf.nbTurn = nbTurn;
     
    		}
    		return copyOf;
    	}
    Ceci fait une copie du composant Grid. A quoi sert cette méthode ? Quand est-elle exécutée ? Il faut savoir que si ton code passe par cette méthode pour effectuer des changements dans le jeu (par exemple, pour traiter la mise à jour du coup de l'ordinateur), le composant produit par celle-ci ne sera jamais affiché, puisqu'il faudrait l'ajouter dans un composant graphique pour que cela soit le cas.

    Si tu as besoin de faire une copie de l'état pour les besoins de l'algorithmique, il vaudrait mieux séparer la vue et le modèle (en général c'est préférable d'ailleurs, même si pour un programme aussi simple que celui que tu fais, on peut s'en passer). Ainsi, tu peux toujours dupliquer le modèle autant que tu veux, et le réaffecter à la vue au besoin, sans avoir à changer les composants dans l'interface graphique.
    Le modèle dans ton cas, c'est le tableau state + nbTurns.

    D'ailleurs ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Grille=Fonction.choice(Grille);
    me fait conforte dans cet idée...

    si l'instance de Grille retournée n'est pas celle qui correspond à celle que tu as ajoutée dans le JPanel Boutons (donc que la méthode Fonction.choice() fait bien appel à makeCopy à un moment, il n'y a aucune raison que l'affichage du composant dans le Bouton se mette à jour, puisque c'est une autre instance qui n'est dans aucune fenêtre sur laquelle on appelle repaint...
    Et du coup, il est tout à fait normal de voir que les coups du joueur s'affichent bien lorsque tu commentes cette ligne, puisque dans ce cas, la variable Grille contient toujours bien la référence d'origine de Grid, et qui est bien affichée.

    Du coup, si tu faisais :
    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
    public class State {
    	public Player[][] state;// le type Player est une enumeration (EMPTY, DOT, CROSS). Le tableau state est la représentation du plateau de jeu (3x3)
    	int nbTurn = 0;
     
    	public State() {
    		state = new Player[3][3];// toutes les cases de state sont mises a Player.EMPTY.
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				state[i][j] = Player.EMPTY;
    			}
    		}
    	}
     
    	public int eval() { // teste à chaque tour si il y a un gagant; retourne 1 si le joueur gagne, -1 si l'ordi gagne, 0 sinon.
    		   if (nbTurn < 5) {
    			return 0;
    		}
    		for (int i = 0; i < 3; i++) {
    			if (state[i][0].equals(state[i][1]) && state[i][0].equals(state[i][2]) && state[i][0].equals(Player.DOT)) {
    				return -1;
    			}
    			if (state[i][0].equals(state[i][1]) && state[i][0].equals(state[i][2]) && state[i][0].equals(Player.CROSS)) {
    				return 1;
    			}
    		}
    		for (int j = 0; j < 3; j++) {
    			if (state[0][j].equals(state[1][j]) && state[0][j].equals(state[2][j]) && state[0][j].equals(Player.DOT)) {
    				return -1;
    			}
    			if (state[0][j].equals(state[1][j]) && state[0][j].equals(state[2][j]) && state[0][j].equals(Player.CROSS)) {
    				return 1;
    			}
    		}
    		if (state[0][0].equals(state[2][2]) && state[0][0].equals(state[1][1]) && state[0][0].equals(Player.DOT)) {
    			return -1;
    		}
    		if (state[0][0].equals(state[2][2]) && state[0][0].equals(state[1][1]) && state[0][0].equals(Player.CROSS)) {
    			return 1;
    		}
    		if (state[0][2].equals(state[2][0]) && state[0][2].equals(state[1][1]) && state[0][2].equals(Player.DOT)) {
    			return -1;
    		}
    		if (state[0][2].equals(state[2][0]) && state[0][2].equals(state[1][1]) && state[0][2].equals(Player.CROSS)) {
    			return 1;
    		}
     
    		return 0;
    	}
     
     
    	public State makeCopy() {
    		State copyOf = new State();
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				copyOf.state[i][j] = state[i][j];
    			}
    			copyOf.nbTurn = nbTurn;
     
    		}
    		return copyOf;
    	}
     
    	public void printG() {
    		for (int i = 0; i < 3; i++) {
    			System.out.println(state[i][0].toString() + state[i][1].toString() + state[i][2].toString());
     
    		}
    	}
     
     
    }
    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
    public class Grid extends JPanel {
     
    	public State state;
     
    	public Grid() {
    		setBackground(Color.BLACK);
    		setPreferredSize(new Dimension(300, 300));
    		state = new State();
    	}
     
    	public void setState(State state) {
    		this.state = state;
    		repaint();
    	}
     
    	public void drawGrid(Graphics g) { // dessine le plateau de jeu (#)
    		g.setColor(Color.WHITE);
    		g.fillRect(95, 0, 10, 300);
    		g.fillRect(195, 0, 10, 300);
    		g.fillRect(0, 95, 300, 10);
    		g.fillRect(0, 195, 300, 10);
    	}
     
    	public void drawDot(Graphics g, int i, int j) {// la grille de jeu et représentée par un tableau 3x3. drawDot() trace un point en position (i,j).
    		if (state.state[i][j].equals(Player.DOT)) {
    			g.setColor(Color.WHITE);
    			int xShift=j * 100;
    			int yShift=i*100;
    			g.fillOval( xShift+ 5, yShift + 5, 85, 85);
    		}
    	}
     
    	public void drawCross(Graphics g, int i, int j) {//trace une croix en position (i,j).
    		if (state.state[i][j].equals(Player.CROSS)) {
    			g.setColor(Color.WHITE);
    			int xShift = j * 100;
    			int yShift = i * 100;
    			int[] xPoints = { 20 + xShift, 15 + xShift, 85 + xShift, 90 + xShift, 20 + xShift };
    			int[] yPoints = { 15 + yShift, 20 + yShift, 90 + yShift, 85 + yShift, 15 + yShift };
    			g.fillPolygon(xPoints, yPoints, 5);
    			int[] sPoints = { 15 + xShift, 20 + xShift, 90 + xShift, 85 + xShift, 15 + xShift };
    			int[] tPoints = { 85 + yShift, 90 + yShift, 20 + yShift, 15 + yShift, 85 + yShift };
    			g.fillPolygon(sPoints, tPoints, 5);
     
    		}
    	}
     
     
    	public void paintComponent(Graphics g) {
    		super.paintComponent(g);
    		drawGrid(g);
    		for (int i = 0; i < 3; i++) {
    			for (int j = 0; j < 3; j++) {
    				drawDot(g, i, j);
    				drawCross(g, i, j);
    			}
    		}
    	}
     
     
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void faireJouerOrdi(); {     
    		Grille.state.nbTurn++; // important pour la fonction Fonction.choice.
    		State state =Fonction.choice(Grille.state); // choisi le prochain coup de l'ordi à partir du plateau de jeu après le coup du joueur.
    		state.printG();
    		Grille.setState(state);// affiche le coup du joueur et le coup de l'ordi en même temps.
    }
    Il faut modifier également actionPerformed. Par exemple :
    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
    		State state = Grille.state;
     
    		if (e.getSource() == UN && state.state[0][0].equals(Player.EMPTY)) {
    			state.state[0][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == DEUX && state.state[0][1].equals(Player.EMPTY)) {
    			state.state[0][1] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == TROIS && state.state[0][2].equals(Player.EMPTY)) {
    			state.state[0][2] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == QUATRE && state.state[1][0].equals(Player.EMPTY)) {
    			state.state[1][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		 if (e.getSource() == CINQ && state.state[1][1].equals(Player.EMPTY)) {
    			state.state[1][1] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == SIX && state.state[1][2].equals(Player.EMPTY)) {
    			state.state[1][2] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == SEPT && state.state[2][0].equals(Player.EMPTY)) {
    			state.state[2][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == HUIT && state.state[2][1].equals(Player.EMPTY)) {
    			state.state[2][1] = Player.CROSS;
    			faireJouerOrdi();
    		}
    		if (e.getSource() == NEUF && state.state[2][2].equals(Player.EMPTY)) {
    			state.state[2][2] = Player.CROSS;
    			faireJouerOrdi();
    		}

    Bon, globalement ton programme présente plusieurs soucis tant au niveau architecture, au niveau technique qu'au niveau fonctionnel. Au niveau architecture, un objet doit être vu comme une boite noire : les autres objets ne devraient pas avoir à manipuler ses attributs, mais passer par des méthodes qui le font.

    Au niveau technique, il y a beaucoup de répétitions de code qui pourraient être simplifiée par des méthodes.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    		if (e.getSource() == UN && state.state[0][0].equals(Player.EMPTY)) {
    			state.state[0][0] = Player.CROSS;
    			faireJouerOrdi();
    		}
    Avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    public void jouerHumain(int x, int y) {
        if ( grille.state.state[x][y].equals(Player.EMPTY) ) {
            state.state[x][y] = Player.CROSS;
    	faireJouerOrdi();
        }
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if (e.getSource() == UN ) {
            jouerHumain(0,0);
    }
    if (e.getSource() == DEUX ) {
            jouerHumain(0,1);
    }
    Et si au lieu d'avoir 9 variables de JButton, tu supprimais ces variables...
    et donc les créer dans le constructeur de Buttons par une boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for(int i=0; i<9; i++) {
    			JButton button = new JButton(String.valueOf(i+1));
    			touches.add(button);
    			int x=i/3;
    			int y=i%3;
    			button.addActionListener(new ActionListener() {
     
    				@Override
    				public void actionPerformed(ActionEvent e) {
    					jouerHumain(x,y);
    				}
    			});
    		}
    Si tu veux pouvoir quand même interagir avec les boutons (ce qui te permettrait d'appeler setEnabled(false) sur un bouton qui correspond à une case jouée par exemple), tu peux les stocker dans un tableau.


    A noter, que quand on boucle sur un tableau, il vaut mieux toujours utiliser ses bornes (par length) qu'une valeur en dur, ce qui est évite, en cas de changement de taille du tableau, d'avoir à modifier le code de toutes les boucles...

    Au niveau fonctionnel, ce qui est le plus gênant pour moi, c'est que le coup du joueur n'est pas visible immédiatement, mais seulement quand l'ordinateur a joué. Si l'ordinateur mets beaucoup de temps à "réfléchir" , c'est plutôt déroutant pour le joueur humain. Pour faire ça, il faudrait utiliser un SwingWorker, par exemple.

    Et enfin, il existe des conventions de nommage en Java : les noms de variables devraient commencer par des minuscules.
    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
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 4
    Par défaut
    Merci beaucoup pour tes explications. Je te répondrais demain je n'ai pas trop le temps de regarder ca maintenant. Bonne soirée!!

  6. #6
    Futur Membre du Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Décembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2019
    Messages : 4
    Par défaut
    Re-bonjour, effectivement j'utilise la méthode makeCopyOf() dans la fonction Fonction.choice. En passant par une classe intermédiaire State, tout fonctionne très bien. Je n'avais pas bien compris le fonctionnement des JPanel. Merci pour ton temps.

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

Discussions similaires

  1. problème avec la méthode repaint
    Par schine dans le forum AWT/Swing
    Réponses: 12
    Dernier message: 09/10/2017, 15h20
  2. Problème avec la méthode repaint()
    Par Askiarsh dans le forum Débuter
    Réponses: 7
    Dernier message: 12/05/2017, 14h53
  3. [débutant] Problème avec la méthode "repaint"
    Par Mag007 dans le forum Langage
    Réponses: 2
    Dernier message: 29/03/2007, 22h35
  4. problème avec la méthode getElementById() dans Firefox
    Par matrouba dans le forum Général JavaScript
    Réponses: 5
    Dernier message: 19/12/2005, 09h55
  5. Problème avec la méthode pack()
    Par tomca dans le forum Langage
    Réponses: 5
    Dernier message: 15/09/2005, 11h58

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