A fully functional Minesweeper game in Java that is similar to the one bundled with Windows, and that can be easily enhanced.
1.import java.awt.BorderLayout;
2.import java.awt.GridLayout;
3.import java.awt.event.InputEvent;
4.import java.util.Random;
5.
6.import javax.swing.JButton;
7.import javax.swing.JFrame;
8.import javax.swing.JOptionPane;
9.import javax.swing.JPanel;
10.import javax.swing.JProgressBar;
11.import javax.swing.JToggleButton;
12.import javax.swing.JToolBar;
13.
14.public class Minesweeper extends JFrame {
15.
16. private int columns = 10;
17. private int rows = 10;
18. private static final long serialVersionUID = 1L;
19. // Stores which cells are bombs and which are not
20. boolean jBombs[][] = new boolean[rows][columns];
21. // Stores information on which cell has been displayed
22. boolean jShown[][] = new boolean[rows][columns];
23. // Stores information on surrounding cells
24. int jCells[][] = new int[rows][columns];
25. private int currX, currY = 0;
26. JToggleButton jButtons[] = new JToggleButton[columns*rows];
27. private JPanel jPanel = null;
28. private JToolBar jToolBar = null;
29. private JPanel jContentPane = null;
30. private JButton jBtnNewGame = null;
31. private JProgressBar jProgressBar = null;
32. /**
33. * This is the default constructor
34. */
35. public Minesweeper() {
36. super();
37. initialize();
38. }
39.
40. /**
41. * This method initializes this
42. *
43. * @return void
44. */
45. private void initialize() {
46. this.setSize(436, 315);
47. this.setContentPane(getJPanel());
48. this.setTitle("Minesweeper");
49. }
50.
51. /**
52. * This method initializes jPanel
53. *
54. * @return javax.swing.JPanel
55. */
56. private JPanel getJPanel() {
57. if (jPanel == null) {
58. jPanel = new JPanel();
59. jPanel.setLayout(new BorderLayout());
60. jPanel.add(getJToolBar(), BorderLayout.NORTH);
61. jPanel.add(getJContentPane(), BorderLayout.CENTER);
62. jPanel.add(getJProgressBar(), BorderLayout.SOUTH);
63. }
64. return jPanel;
65. }
66.
67. /**
68. * This method initializes jToolBar
69. *
70. * @return javax.swing.JToolBar
71. */
72. private JToolBar getJToolBar() {
73. if (jToolBar == null) {
74. jToolBar = new JToolBar();
75. jToolBar.setFloatable(false);
76. jToolBar.add(getJBtnNewGame());
77. }
78. return jToolBar;
79. }
80.
81. /**
82. * This method initializes jContentPane
83. *
84. * @return javax.swing.JPanel
85. */
86. private JPanel getJContentPane() {
87. if (jContentPane == null)
88. {
89. GridLayout gridLayout = new GridLayout();
90. gridLayout.setRows(rows);
91. gridLayout.setColumns(columns);
92. jContentPane = new JPanel();
93. jContentPane.setLayout(gridLayout);
94.
95. BuildBoard();
96. }
97.
98. return jContentPane;
99. }
100.
101. private void BuildBoard()
102. {
103. // JContentPane will call this function before jProgressBar was
built when first started
104. if(jProgressBar != null) // So we check to see if the progress
.bar has been initialized
105. {
106. jProgressBar.setValue(0);
107. }
108. jContentPane.removeAll();
109. int i = 0;
110. for(int x = 0; x < rows; x++)
111. {
112. for(int y = 0; y < columns; y++)
113. {
114. currX = x;
115. currY = y;
116. Random randBomb = new Random();
117. jBombs[x][y] = randBomb.nextBoolean() && randBomb.nextBoolean() && randBomb.nextBoolean(); // 13% chances of a bomb
118. jButtons[i] = new JToggleButton("");
119. jButtons[i].addMouseListener(new java.awt.event.MouseAdapter(){
120. public void mouseReleased(java.awt.event.MouseEvent e) {
121. if(e.getModifiers() == InputEvent.BUTTON3_MASK)
122. {
123. markCell(e);
124. }
125. else if(e.getModifiers() == InputEvent.BUTTON1_MASK)
126. {
127. showCell(e);
128. }
129. }
130. });
131. jContentPane.add(jButtons[i]);
132. i++;
133. }
134. }
135.
136. // Build the board
137 for(int x = 0; x < rows; x++)
138. {
139. for(int y = 0; y < columns; y++)
140. {
141. jCells[x][y] = bombCount(x, y);
142. jShown[x][y] = false; // Reset previous values
143. }
144. }
145. jContentPane.setEnabled(true);
146. this.repaint();
147. this.validate();
148. }
149.
150. /**
151. * This method initializes jBtnNewGame
152. *
153. * @return javax.swing.JButton
154. */
155. private JButton getJBtnNewGame() {
156. if (jBtnNewGame == null) {
157. jBtnNewGame = new JButton();
158. jBtnNewGame.setText("New Game");
159. jBtnNewGame.addMouseListener(new java.awt.event.MouseAdapter() {
160. public void mouseReleased(java.awt.event.MouseEvent e) {
161. BuildBoard();
162. }
163. });
164. }
165. return jBtnNewGame;
166. }
167.
168. /**
169. * This method initializes jProgressBar
170. *
171. * @return javax.swing.JProgressBar
172. */
173. private JProgressBar getJProgressBar() {
174. if (jProgressBar == null) {
175. jProgressBar = new JProgressBar();
176. jProgressBar.setMaximum(columns * rows);
177. }
178. return jProgressBar;
179. }
180.
181. public static void main(String args[](
182. {
183.
184. }
185.
186. // Displays all cells marked as bombs
187. private void showAllBombs()
188. {
189. for(int x = 0; x < rows; x++)
190. {
191. for(int y = 0; y < columns; y++)
192. {
193. if(jBombs[x][y] == true)
194. {
195. JToggleButton jButton = findButton(x,y);
196. if(jButton.isEnabled()) // Don't go over the ones that were already counted
197. {
198. jProgressBar.setValue(jProgressBar.getValue() + 1);
199. }
200. jButton.setText("X");
201. jButton.setSelected(true);
202. jButton.setEnabled(false);
203. }
204. }
205. }
206. }
207.
208. private void clearCells(int x, int y)
209. {
210. // If the cell is in bounds
211. if(inBounds(x, y))
212. {
213. if(!jShown[x][y] && jBombs[x][y] == false)
214. {
215. jShown[x][y] = true;
216. JToggleButton jButton = findButton(x,y);
217. if(jCells[x][y] > 0)
218. {
219. jButton.setText(Integer.toString(jCells[x][y]));
220. }
221. else
222. {
223. jButton.setText("");
224. }
225. if(jButton.isEnabled()) // Don't go over the ones that were already counted
226. {
227. jProgressBar.setValue(jProgressBar.getValue() + 1);
228. }
229. jButton.setSelected(true);
230. jButton.setEnabled(false);
231.
232. // Check surrounding cells
233. if(jCells[x][y] == 0)
234. {
235. for(int r = -1; r <= 1; r++)
236. {
237. for(int c = -1; c <= 1; c++)
238. {
239. clearCells(x + r, y + c);
240. }
241. }
242. }
243. }
244. }
245. }
246.
247. private boolean inBounds(int x, int y)
248. {
249. // Check if position is within bounds
250. return 0 <= x && x < jCells.length && 0 <= y && y < jCells[x].length;
251. }
252.
253. private boolean isBomb(JToggleButton jButton)
254. {
255. int i = 0;
256. for(int x = 0; x < rows; x++)
257. {
258. for(int y = 0; y < columns; y++)
259. {
260. if(jButton == jButtons[i])
261. {
262. currX = x;
263. currY = y;
264. return jBombs[x][y];
265. }
266. i++;
267. }
268. }
269. return false;
270. }
271.
272. private void disableBoard()
273. {
274. for(int x = 0; x < rows; x++)
275. {
276. for(int y = 0; y < columns; y++)
277. {
278. JToggleButton jButton = findButton(x,y);
279. jButton.setEnabled(false);
280. }
281. }
282. }
283.
284. private JToggleButton findButton(int x, int y)
285. {
286. return jButtons[(x*rows+y)];
287. }
288.
289. private void showCell(java.awt.event.MouseEvent e)
290. {
291. JToggleButton jButton = (JToggleButton)e.getSource();
292. if(jButton.isEnabled())
293. {
294. jProgressBar.setValue(jProgressBar.getValue() + 1);
295. jButton.setEnabled(false);
296.
297. if(isBomb(jButton))
298. {
299. showAllBombs();
300. jButton.setEnabled(false);
301. JOptionPane.showMessageDialog(null,"You lost " + Math.round((jProgressBar.getPercentComplete() * 100)) + "% through.", "You Lost!", JOptionPane.INFORMATION_MESSAGE);
302. disableBoard();
303. }
304. else
305. {
306. if(jCells[currX][currY] > 0)
307. {
308. jButton.setText(Integer.toString(jCells[currX][currY]));
309. }
310. else if(jCells[currX][currY] == 0)
311. {
312. clearCells(currX, currY);
313. }
314. }
315. }
316. }
317.
318. private int bombCount(int x, int y)
319. {
320. int bombCount = 0;
321.
322. // Count bombs in surrounding cells
323. for(int r = -1; r <= 1; r++)
324. {
325. for(int c = -1; c <= 1; c++)
326. {
327. int newx = x + r;
328. int newy = y + c;
329. if(inBounds(newx, newy))
330. {
331. if(jBombs[newx][newy] == true)
332. {
333. bombCount++;
334. }
335. }
336. }
337. }
338. return bombCount;
339. }
340.
341. private void markCell(java.awt.event.MouseEvent e) // To set and remove the "!" flag
342. {
343. JToggleButton jButton = (JToggleButton)e.getSource();
344. if(jButton.isEnabled())
345. {
346. if(jButton.getText() != "!")
347. {
348. jButton.setText("!");
349. }
350. else
351. {
352. jButton.setText("");
353. }
354. }
355. }
356. } // @jve:decl-index=0:visual-constraint="10,10"