Bonjour,

J'ai écrit un démineur pour un projet universitaire. Cependant, j'ai un problem avec un de mes JPannel qui se vois "effacé" lors de l'apparition d'une autre fenetre sur mon démineur. Exemple :

Fenetre normale


Fenetre buggé


Voici le code de la classe réalisant l'affichage :

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
 
package pobj.game.demineur.view;
 
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
 
import javax.swing.Box;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
/**
 * La fenêtre globale du Démineur
 * @author caroline chopinaud
 */
public class DemineurMainWindow extends JFrame {
	private DemineurView view;
	private JPanel gamePanel;
 
	public DemineurMainWindow (DemineurView view){
		super("Démineur");
		this.view = view;
		makeGUI();
		this.pack();
		this.setVisible(true);
	}
 
	private void makeGUI(){
		gamePanel = new JPanel();
		JPanel up = new JPanel();
		JLabel minesRestantes = new JLabel("10");
		JLabel tempsEcoule = new JLabel("25");
		JButton newButton = new JButton();
		newButton.setIcon(new ImageIcon(DemineurView.class.getResource("/pobj/game/demineur/data/Cool.png")));
		newButton.setPreferredSize(new Dimension(30,30));
		newButton.setActionCommand("NEW");
 
		gamePanel.setLayout(new BorderLayout());
		gamePanel.add(view, BorderLayout.CENTER);
 
		gamePanel.add(up, BorderLayout.NORTH);
 
//		Box hbox = Box.createHorizontalBox();
//		hbox.add(minesRestantes);
//		hbox.add(Box.createHorizontalStrut(20));
//		hbox.add(newButton);
//		hbox.add(Box.createHorizontalStrut(20));
//		hbox.add(tempsEcoule);
//		up.add(hbox);
 
		up.setLayout(new FlowLayout());
		up.add(newButton);
 
		// TODO: créer les menus
 
		this.setContentPane(gamePanel);
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
	}
 
	// TODO: créer un MenuController pour gérer les menus
 
} // DemineurMainWindow
Comme vous pouvez constater, j'ai mis en commentaire la méthode avec les Box, pour m'assurer que le problème ne venait pas de là. Mais ça fait pareil avec le JPAnnel tout simple et un seul boutton.

Je pensais que les objets de type JPannel faisaient appel automatiquement à la méthode repaint() lorsqu'un événement système se produisait. D'ailleurs, mon panel CENTER qui contient la grille fonctionne parfaitement si je passe une autre fenetre dessus, il ne s'efface pas. Voici le code de celui-ci au cas ou :

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
 
package pobj.game.demineur.view;
 
 
import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.ArrayList;
 
import javax.swing.JPanel;
 
import pobj.game.demineur.model.DemineurModel;
import pobj.game.demineur.model.ModelChangeEvent;
import pobj.game.demineur.model.ModelChangeListener;
 
/**
 * La vue du Démineur
 * @author caroline chopinaud
 */
public class DemineurView extends JPanel implements ModelChangeListener  {
 
	/** La hauteur d'une case */
	public final static int HAUTEUR_CASE = 30;
 
	/** La largeur d'une case */
	public final static int LARGEUR_CASE = 30;
 
	/** Le modèle du démineur */
	private DemineurModel model;
 
	/** Le tableau des vues des Cases */
	private CaseView tableauCase[][];
 
	/** La liste des écouteurs de notification de changement au niveau de la vue */
	private ArrayList<ViewChangeListener> changeListeners;
 
	/**
         * Création d'une vue du Démienur
         * @param model le modèlé du Démineur
         */
	public DemineurView(DemineurModel model) {
        this.model = model;
 
        // TODO: ajouter la vue "this" comme écouteur du modèle pour les ModelChangeEvent
        model.addModelChangeListener(this);
 
        // TODO: construire la liste des écouteur de changement de vue
        changeListeners = new ArrayList<ViewChangeListener>();
 
        // création de la vue
        makeGUI();
    }
 
	/**
         * Initialisation graphique de la vue du Démineur. Tout en vrac mais on pourra séparer comme dans le cours.   
         */	
	private void makeGUI() {
		setLayout(new GridLayout(model.getnbCol(), model.getnbRow()));
		setPreferredSize (new Dimension(model.getnbCol()*LARGEUR_CASE, model.getnbRow()*HAUTEUR_CASE));
		tableauCase = new CaseView[model.getnbCol()][model.getnbRow()];
		CaseView maCase;
 
		for (int i = 0; i < model.getnbCol(); i++) {
			for (int j = 0; j < model.getnbRow(); j++) {
				maCase = new CaseView(i, j, this, model.getCase(i, j));
				add(maCase);
				tableauCase[i][j] = maCase;
			}
		}
	}
 
	/**
         * Accesseur au modèle du jeu
         * @return le modèle du jeu
         */
	public DemineurModel getModel(){
		return model;
	}
 
	/**
         * Enregistre un écouteur de la vue
         * @param l l'écouteur du modèle à ajouter
         */
    public void addViewChangeListener(ViewChangeListener l) {
        changeListeners.add(l);
    }
 
    /**
     * Désenregistre un écouteur de la vue
     * @param l l'écouteur du modèle à supprimer
     */
    public void removeViewChangeListener(ViewChangeListener l) {
        changeListeners.remove(l);
    }
 
    /**
     * Notifie les écouteurs d'un changement dans la vue
     * @param event l'événement à envoyer
     */
    public void fireModelChange(ViewChangeEvent event) {
    	for(ViewChangeListener l : changeListeners){ 
            l.viewChanged(event);
    	}
    }
 
	/**
         * Lors d'un changement dans le modèle. Ici on affiche si la partie a été gagnée ou perdue. Il faudrait
         * le faire via le smiley.
         * Réafiche à la case ayant généré cet événement. Réaffiche tout le jeu si la partie est perdue.
         */
	public void modelChanged(ModelChangeEvent evt){
		//System.out.println("je suis dans modelChanged");
		if (evt.getStatut() == evt.GAGNE) {
			System.out.println("bravo, vous avez gagné!");
		}
		else if (evt.getStatut() == evt.PERDU) {
			System.out.println("vous avez perdu!");
			for (int i = 0; i < tableauCase.length; i++) {
				for (int j = 0; j < tableauCase[0].length; j++) {
					tableauCase[i][j].drawCase();
				}
			}
		}
		else {
			tableauCase[evt.getCol()][evt.getRow()].drawCase();
		}
	}
 
 
}// DemineurVue
J'espère avoir été assez clair