Bonjour,

je travaille actuellement sur un Demineur (un petit projet scolaire), quelque chose de simple mais qui me pose un souci, je m'explique:

Comme dans tout bon démineur, lorsque l'on clique sur une case vide, elle affiche le nombre de bombes qui lui sont contigües, et là problème... pas dans l’algorithme non, mais dans l'affichage, et ce sous Windows uniquement

En effet, sous MacOS, le chiffre s'affiche sans problème, sous Windows (7 et XP testés) j'ai un joli "..." (avec un SOP de "debug" je contrôle d'ailleurs que la valeur est correcte)

Je vous propose mon code comme appui (la ligne 197 de la classe Case est le point sensible je pense)

Classe Case ::
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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
 
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
 
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
 
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.ImageIcon;
 
import java.util.*;
 
abstract class Case extends JButton implements  MouseListener {
	public static final int tailleCase = 17;
	public static final int MARQUEE = 2, DECOUVERTE = 1;
 
	public static final double ratio = 2.0/15.0;
 
	static int nbCaseLargeur = 0;
	static int nbCaseHauteur = 0;
 
	static Case tableau[][] = null;
 
	int x, y; //coordonees d'un bouton/case
	int statut; //case marquee ou decouverte
 
	Case(int xx, int yy) {
		x = xx;
		y = yy;
		setPreferredSize(new Dimension(tailleCase, tailleCase));
	}
 
	public static JPanel initJeu(int l, int h) {
		nbCaseLargeur = l + 2;
		nbCaseHauteur = h + 2;
 
		JPanel terrainDeJeu = new JPanel(new FlowLayout());
		//le constructeur de GridLayout(lignes, colonnes)
		GridLayout grilleDeJeu = new GridLayout(nbCaseLargeur, nbCaseHauteur);
 
		tableau = new Case[nbCaseLargeur][nbCaseHauteur];
 
		//CrŽation d'un ArraList<String> stockant les coordonnees des bombes sans doublons
		int nBombes = (int) (ratio * l * h);
		int x, y;
		List<String> maListe = new ArrayList<String>();
		for (int i = 0; i < nBombes; i++) {
			do {
				x = (int) (Math.random() * l) + 1;
				y = (int) (Math.random() * h) + 1;
			} while ((x == 0) || (y == 0) || (x == nbCaseLargeur - 1) || (y == nbCaseHauteur) || (maListe.contains(x + ";" + y)));
			maListe.add(x + ";" + y);
		}		
		Collections.sort(maListe);
 
		//CrŽation de la grille de jeu, chaque case du tableau est instanciee puis incorporee au JPanel
		for (int i = 0; i < nbCaseLargeur; i++) {
        	for (int j = 0; j < nbCaseHauteur; j++) {
        		//Ajout des CaseBord qui sont masquees via leur constructeur (de meme pour les dimensions)
        		if ((i == 0) || (j == 0) || (i == nbCaseLargeur - 1) || (j == nbCaseHauteur - 1)) {
		        	tableau[i][j] = new CaseBord(i, j);
					terrainDeJeu.add(tableau[i][j]);
				//Ajout des CaseBombe
        		} else if (maListe.contains(i + ";" +j)) {
        			tableau[i][j] = new CaseBombe(i, j);
        			terrainDeJeu.add(tableau[i][j]);
				//Ajout des CaseVide
        		} else {
        			tableau[i][j] = new CaseVide(i, j);
					terrainDeJeu.add(tableau[i][j]);
        		}
        	}
		}
 
		terrainDeJeu.setLayout(grilleDeJeu);
		return terrainDeJeu;
	}
 
	boolean estDecouverte() {
    	return (statut == DECOUVERTE);
    }
 
	boolean estMarquee() {
    	return (statut == MARQUEE);
    }
 
	boolean marqueCase() {
    	if (statut == MARQUEE) {
    		this.setIcon(null);
    		statut = 0;
    	} else if (statut == DECOUVERTE) {
    		this.setIcon(null);
    	} else {
    		this.setIcon(new ImageIcon("images/drapeau.gif"));
    		statut = MARQUEE;
    	}
    	return gagne();
    }
 
	static boolean gagne() {
		for(int i = 1; i < nbCaseLargeur-1;i++)
		    for(int j = 1; j < nbCaseHauteur-1;j++) {
				if (tableau[i][j].estMarquee() && !(tableau[i][j].existeBombe() )) return false;
				if ((!tableau[i][j].estMarquee()) && (tableau[i][j].existeBombe() )) return false;
		    }
		return true;
    }
 
	public static void decouvreTous() {
		for (int i = 0 ; i < nbCaseLargeur; i++)
		    for (int j = 0 ; j < nbCaseHauteur; j++)
		    	tableau[i][j].decouvreCase();
    }
 
	public String toString() {
    	return "@";
    }
 
	abstract boolean existeBombe();
 
    abstract int nombreBombes();
 
    abstract boolean decouvreCase();
}
 
class CaseBord extends Case {
	CaseBord(int xx, int yy) {
		super(xx, yy);
		setVisible(false);
	}
 
	public String toString() {
    	return "";
    }
 
	public boolean existeBombe() {
		return false;
	};
 
	public int nombreBombes() {
		throw new Error("Ne doit pas etre appelee");
	};
 
	public boolean decouvreCase() {
		return false;
	};
 
	//Les methodes de contole de la souris ne doivent pas etre appelees sur les CaseBord
	public void mouseClicked(MouseEvent arg0) {}
 
	public void mouseEntered(MouseEvent arg0) {}
 
	public void mouseExited(MouseEvent arg0) {}
 
	public void mousePressed(MouseEvent arg0) {}
 
	public void mouseReleased(MouseEvent arg0) {}
}
 
class CaseVide extends Case {
	CaseVide(int xx, int yy) {
		super(xx, yy);
		addMouseListener(this);
	}
 
	public String toString() {
		if (estDecouverte()) return "" + nombreBombes();
		if (estMarquee()) return "M";
		return "";
    }
 
	public boolean existeBombe() {
		return false;
	};
 
	public int nombreBombes() {
		int nb = 0;
		if (tableau[x-1][y].existeBombe()) nb++;
		if (tableau[x+1][y].existeBombe()) nb++;
		if (tableau[x][y-1].existeBombe()) nb++;
		if (tableau[x][y+1].existeBombe()) nb++;
		if (tableau[x-1][y-1].existeBombe()) nb++;
		if (tableau[x-1][y+1].existeBombe()) nb++;
		if (tableau[x+1][y-1].existeBombe()) nb++;
		if (tableau[x+1][y+1].existeBombe()) nb++;
		return nb;
	};
 
	public boolean decouvreCase() {	
		this.setIcon(null);
 
		//Chercher pourquoi les cases sont mal gerees sous Windows
		if (nombreBombes() == 0)
			this.setIcon(new ImageIcon("images/zero.gif"));
		else
			this.setText(Integer.toString(nombreBombes()));
 
		//Utilise pour les ImageIcon sur les cases
		//Creer un test (methode) qui s'assure de la presence des images pour les creer (genre if getFile("image").exists) 	
		/*switch (nombreBombes()) {
			case 0: this.setIcon(new ImageIcon("images/zero.gif")); break;
			case 1: this.setIcon(new ImageIcon("images/un.gif")); break;
			case 2: this.setIcon(new ImageIcon("images/deux.gif")); break;
			case 3: this.setIcon(new ImageIcon("images/trois.gif")); break;
			case 4: this.setIcon(new ImageIcon("images/quatre.gif")); break;
			case 5: this.setIcon(new ImageIcon("images/cinq.gif")); break;
			case 6: this.setIcon(new ImageIcon("images/six.gif")); break;
			case 7: this.setIcon(new ImageIcon("images/sept.gif")); break;
			case 8: this.setIcon(new ImageIcon("images/huit.gif")); break;
		}*/
		if ((!estDecouverte()) && (!estMarquee())) {
    		statut = DECOUVERTE;
    		if (nombreBombes() == 0) {
				tableau[x-1][y].decouvreCase();
				tableau[x+1][y].decouvreCase();
				tableau[x-1][y-1].decouvreCase();
				tableau[x-1][y+1].decouvreCase();
				tableau[x+1][y-1].decouvreCase();
				tableau[x+1][y+1].decouvreCase();
				tableau[x][y-1].decouvreCase();
				tableau[x][y+1].decouvreCase();
    		}
    	}
    	return false;
	};
 
	public void mouseClicked(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON1) {
			this.decouvreCase();
			if (gagne()) Demineur.recommancerPartie("GAGNE");
		} else if (e.getButton() == MouseEvent.BUTTON3) {
			this.marqueCase();
			if (gagne()) Demineur.recommancerPartie("GAGNE");
		}
	}
 
	public void mouseEntered(MouseEvent arg0) {}
 
	public void mouseExited(MouseEvent arg0) {}
 
	public void mousePressed(MouseEvent arg0) {}
 
	public void mouseReleased(MouseEvent arg0) {}
}
 
class CaseBombe extends Case {
	CaseBombe(int xx, int yy) {
		super(xx, yy);
		addMouseListener(this);
	}
 
	public String toString() {
		if (estDecouverte()) return "X";
    	if (estMarquee()) return "M";
    	return "";
    }
 
	public boolean existeBombe() {
		return true;
	}
 
	public int nombreBombes() {
		return -1;
	}
 
	public boolean decouvreCase() {
   		statut = DECOUVERTE;
   		this.setIcon(new ImageIcon("images/mine.gif"));
    	return true;
	}
 
	public void mouseClicked(MouseEvent e) {
		if (e.getButton() == MouseEvent.BUTTON1) {
			decouvreTous();
			Demineur.recommancerPartie("PERDU");
		} else if (e.getButton() == MouseEvent.BUTTON3) {
			this.marqueCase();
			if (gagne()) Demineur.recommancerPartie("GAGNE");
		}
	}
 
	public void mouseEntered(MouseEvent arg0) {}
 
	public void mouseExited(MouseEvent arg0) {}
 
	public void mousePressed(MouseEvent arg0) {}
 
	public void mouseReleased(MouseEvent arg0) {}
}
Classe Demineur ::
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
 
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
 
public class Demineur extends JFrame implements ActionListener {
	static int largeur = 10;
	static int hauteur = 10;
 
	private JButton btnTaille = new JButton("Taille grille");
 
	static JFrame jeuEnCours;
 
	JPanel header = new JPanel(new FlowLayout());
	JPanel zoneDeJeu = new JPanel(new FlowLayout());
 
	Demineur() {
		setTitle("Demineur");
		//setSize(largeur * Case.tailleCase + 100, hauteur * Case.tailleCase + 100);
 
		Container c = getContentPane();
 
		btnTaille.addActionListener(this);
 
		header.add(btnTaille);
		zoneDeJeu.add(Case.initJeu(largeur, hauteur));
 
		c.add(header, BorderLayout.NORTH);
		c.add(zoneDeJeu, BorderLayout.SOUTH);
 
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
 
	public static void main(String args[]) {
		Demineur d = new Demineur();
 
		d.setVisible(true);
		d.setLocationRelativeTo(null);
		d.setResizable(true);
		d.pack();
 
		selectJeuEnCours(d);
	}
 
	public int largeur() {
    	return Case.nbCaseLargeur;
    }
 
    public int hauteur() {
    	return Case.nbCaseHauteur;
    }
 
    //On variabilise jeuEnCours avec la JFrame nouvellement creee, de facon a la liberer (dispose()) lors d'une nouvelle partie
    public static void selectJeuEnCours(JFrame frame) {
    	jeuEnCours = frame;
    }
 
    public static void recommancerPartie(String statut) {
    	if (javax.swing.JOptionPane.showConfirmDialog(null, statut, "Voulez-vous rejouer?", JOptionPane.YES_NO_OPTION) == 0) {
    		jeuEnCours.dispose();
    		main(null);
    	} else {
    		System.exit(0);
    	}
    }
 
    public static void setLargeur(int l) {
    	largeur = l;
    }
 
    public static void setHauteur(int h) {
    	hauteur = h;
    }
 
    public void actionPerformed(ActionEvent e) {
		if (e.getSource() == btnTaille) {
			Option.main(null);
		}
	}
}
Classe Option ::
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
 
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JButton;
 
class Option extends JFrame implements ActionListener {
	private JTextField textFieldLargeur;
	private JTextField textFieldHauteur;
 
	JButton buttonOK = new JButton("OK");
	JButton buttonCancel = new JButton("Cancel");
 
	Option() {
		JPanel zoneOption = new JPanel(new FlowLayout());
 
		Container c = getContentPane();
 
		JLabel labelLargeur = new JLabel("Largeur: ");
		labelLargeur.setBounds(29, 24, 55, 16);
		zoneOption.add(labelLargeur);
 
		textFieldLargeur = new JTextField();
		textFieldLargeur.setBounds(96, 18, 134, 28);
		zoneOption.add(textFieldLargeur);
		textFieldLargeur.setColumns(10);
 
		JLabel labelHauteur = new JLabel("Hauteur: ");
		labelHauteur.setBounds(29, 65, 58, 16);
		zoneOption.add(labelHauteur);
 
		textFieldHauteur = new JTextField();
		textFieldHauteur.setBounds(96, 59, 134, 28);
		zoneOption.add(textFieldHauteur);
		textFieldHauteur.setColumns(10);
 
		buttonCancel.setBounds(130, 99, 86, 29);
		buttonCancel.addActionListener(this);
		zoneOption.add(buttonCancel);
 
		buttonOK.setBounds(228, 99, 117, 29);
		buttonOK.addActionListener(this);
		zoneOption.add(buttonOK);
 
		c.add(zoneOption);
	}
 
	public int getUserLargeur() {
		try {
			//System.out.println(Integer.parseInt(textFieldLargeur.getText()));
			return (int) Integer.parseInt(textFieldLargeur.getText());
		} catch (NumberFormatException ex) {
			//System.out.println(ex.getMessage());
			return -1;
		}
	}
 
	public int getUserHauteur() {
		try {
			//System.out.println(Integer.parseInt(textFieldHauteur.getText()));
			return (int) Integer.parseInt(textFieldHauteur.getText());
		} catch (NumberFormatException ex) {
			//System.out.println(ex.getMessage());
			return -1;
		}
	}
 
	public static void main(String args[]) {
		Option fenTaille = new Option();
 
		fenTaille.setVisible(true);
		fenTaille.setLocationRelativeTo(null);
		fenTaille.setResizable(false);
		fenTaille.pack();
	}
 
	public void actionPerformed(ActionEvent e) {
		if (e.getSource() == buttonOK) {
			Demineur.setLargeur(getUserLargeur());
			Demineur.setHauteur(getUserHauteur());
			if ((Demineur.hauteur > 1) && (Demineur.hauteur > 1)) {
				Demineur.recommancerPartie("NOUVELLE PARTIE");
				this.dispose();
			} else {
				this.dispose();
			}
		} else if (e.getSource() == buttonCancel) {
			this.dispose();
		}
	}	
}
Si quelqu'un a une piste, j'ai regardé les divers topics du forum, ainsi que quelques recherches Google mais rien de très probant, d'ailleurs effectuer une recherche google avec "..." comme paramètre n'est pas des plus explicite

En vous remerciant

Edit :: après un test sous CentOS (qui utilise la JVM Sun je crois, comme Windows...) même constat que sous Windows