-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathUI.java
321 lines (278 loc) · 11.4 KB
/
UI.java
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
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
/** MineSweeper
* @author Chase Carnaroli
*
* Controls the User Interface and communicates with the controller
*
* INSTANCE VARIABLES
* Game myGame // Controller
* JButton[][] buttonGrid // Grid of buttons representing the minefield
* int NUM_ROWS // Number of rows on the board
* int NUM_COLS // Number of columns on the board
* int boardSize // Size of the board
* Dimension buttonSize // Dimension of each button
* Icon flag // Image of a MineSweeper flag
*
* METHODS
* updateDisplay() // Updates the display based off of the board stored in the model
* showAllMines() // Updates the display to show all mines except tiles that are flagged
* flagAllMines() // Updates display to flag all the mines
* showWrongFlags() // Updates the display to show each each tile with a flag && without a mine
* showDetonatedMine(Location) // Turns detonated tile red
* flag(Location) // Flags tile at this location
* unFlag(Location) // Unflags tile at this location
* question(Location) // Question marks tile at this location
* displayWinner(Result) -> boolean // Displays message with the end result; then asks if player wants to play again
* returns true if user clicks ‘yes’ or ‘false’ if user clicks ‘no’
* clearDisplay() // Resets all of the JButtons on the grid
* endProgram() // Ends program and exits window
*/
import java.awt.*; // import Container
import java.awt.image.BufferedImage;
import java.util.*; // import ArrayList
import javax.swing.*; // import JFrame
import java.awt.event.*; // import event listener
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class UI extends JFrame
{
// instance variables
private Game myGame;
private JButton[][] buttonGrid;
private int NUM_ROWS, NUM_COLS, boardSize;
private Dimension buttonSize;
private StretchIcon flag, mine;
// menu options
JMenuBar menuBar;
JMenu options, help;
JMenuItem pauseItem, restartItem, quitItem;
// status bar
JPanel statusBar;
// post: constructor – constructs window with a GridLayout and
// a 3 x 3 grid of JButton components and a ButtonHandler; initializes
// reference to ‘game’ object
public UI(Game game)
{
super("MineSweeper");
myGame = game;
boardSize = game.getBoardSize();
NUM_ROWS = boardSize;
NUM_COLS = boardSize;
// Set up window
Container container = getContentPane();
container.setLayout( new GridLayout(NUM_ROWS, NUM_COLS) );
// Set up buttons
buttonGrid = new JButton[boardSize][boardSize];
for(int r = 0; r < boardSize; r++){
for(int c = 0; c < boardSize; c++){
buttonGrid[r][c] = new JButton();
container.add(buttonGrid[r][c]);
buttonGrid[r][c].addMouseListener(new MouseHandler(r,c));
buttonGrid[r][c].setFocusPainted(false); // gets rid of box outlining text of selected box
}
}
buttonSize = buttonGrid[0][0].getSize();
// MENU
// Menu Bar
menuBar = new JMenuBar();
// Option menu
options = new JMenu("Game");
menuBar.add(options);
// Sub Option Items
//Pause
pauseItem = new JMenuItem("Pause");
options.add(pauseItem);
// Restart
restartItem = new JMenuItem("Reset", KeyEvent.VK_T);
restartItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
myGame.resetGame();
}
});
options.add(restartItem);
// Quit
quitItem = new JMenuItem("Quit", KeyEvent.VK_T);
quitItem.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
System.exit(0);
}
});
options.add(quitItem);
// Adds menu bar to screen
this.setJMenuBar(menuBar);
// code for the icons
flag = new StretchIcon("MineSweeperFlag.gif"); // flag icon
mine = new StretchIcon("Mine.png"); // mine icon
// DON'T FORGET TO INCLUDE THIS CODE - otherwise you will not
// be able to close your application!!!
addWindowListener(new java.awt.event.WindowAdapter()
{
public void windowClosing(WindowEvent evt) {
System.exit(0);
}
}
);
// Set window size and show window
Dimension screenSize = new Dimension(650,650);
setMinimumSize(screenSize); // width=700, height=700
setVisible(true);
}
/**
* Updates the display based off of the board stored in the model
* post: displays ‘player’ char in JButton specified by ‘loc’
*/
public void updateDisplay()
{
for(int r = 0; r < boardSize; r++){
for(int c = 0; c < boardSize; c++){
Location loc = new Location(r,c);
Tile pos = myGame.getMineField().getTile(loc);
JButton button = buttonGrid[r][c];
if(pos.isTurned()){
button.setText(pos.toString());
button.setForeground(pos.getColor());
button.getModel().setPressed(true);
button.setEnabled(false);
}
}
}
}
/**
* Updates the display to show all mines except tiles that are flagged
* post: displays each mine on the board except tiles that are flagged
*/
public void showAllMines(){
for(int r = 0; r < boardSize; r++){
for(int c = 0; c < boardSize; c++){
Location loc = new Location(r,c);
Tile tile = myGame.getMineField().getTile(loc);
if(tile.hasMine() && !tile.isFlagged()){
buttonGrid[r][c].setIcon(mine);
}
}
}
}
/**
* Updates the display to show each each tile with a flag && without a mine
* post: displays a red "X" on each tile with a flag && without a mine
*/
public void showWrongFlags(){
for(int r = 0; r < boardSize; r++){
for(int c = 0; c < boardSize; c++){
Location loc = new Location(r,c);
Tile tile = myGame.getMineField().getTile(loc);
if(tile.isFlagged() && !tile.hasMine()){
unFlag(loc);
buttonGrid[r][c].setForeground(Color.red);
buttonGrid[r][c].setText("X");
}
}
}
}
/**
* Turns detonated tile red
* post: tile with detonated mine gets background turned red
*/
public void showDetonatedMine(Location loc){
buttonGrid[loc.getRow()][loc.getCol()].setBackground(Color.red); // sets background to red
buttonGrid[loc.getRow()][loc.getCol()].setBorderPainted(false); // gets rid of button border
}
/**
* Updates display to flag all the mines
* post: all mines on the board are flagged
*/
public void flagAllMines(){
for(int r = 0; r < boardSize; r++){
for(int c = 0; c < boardSize; c++){
Location loc = new Location(r,c);
if(myGame.getMineField().getTile(loc).hasMine()){
flag(loc);
}
}
}
}
// Flags tile at this location
public void flag(Location loc){
buttonGrid[loc.getRow()][loc.getCol()].setText("");
buttonGrid[loc.getRow()][loc.getCol()].setIcon(flag);
}
// Unflags tile at this location
public void unFlag(Location loc){
buttonGrid[loc.getRow()][loc.getCol()].setIcon(null);
buttonGrid[loc.getRow()][loc.getCol()].setText("");
}
// Question marks tile at this location
public void question(Location loc){
buttonGrid[loc.getRow()][loc.getCol()].setIcon(null);
buttonGrid[loc.getRow()][loc.getCol()].setText("?");
}
// post: displays message with the given result; then displays question
// “Do you want to play again?” and returns true if user clicks ‘yes’
// or ‘false’ if user clicks ‘no’
public boolean displayWinner (Result result){
updateDisplay();
int response = JOptionPane.showConfirmDialog(this,result.toString() + "\nDo you want to play again?", "Game Over", JOptionPane.YES_NO_OPTION);
if(response == JOptionPane.YES_OPTION){
return true;
} else {
return false;
}
}
// post: resets all of the JButtons on the grid
public void clearDisplay()
{
// resets grid to null for every position
for(int r = 0; r < boardSize; r++){
for(int c = 0; c < boardSize; c++){
buttonGrid[r][c].setIcon(null);
buttonGrid[r][c].setText(null);
buttonGrid[r][c].getModel().setPressed(false);
buttonGrid[r][c].setEnabled(true);
buttonGrid[r][c].setBackground(null);
buttonGrid[r][c].setBorderPainted(true);
}
}
}
// post: ends program and exits window
public void endProgram()
{
System.exit(0);
}
// Handles mouse clicks on the board
private class MouseHandler extends MouseAdapter
{
// Instance Variables
public int row, col;
// Constructor
public MouseHandler(int r, int c){
row = r;
col = c;
}
public void mouseClicked(MouseEvent event){
Click clickType = Click.NA;
if(event.getButton() == MouseEvent.BUTTON1){
clickType = Click.TURN_TILE;
}
if(event.getButton() == MouseEvent.BUTTON3){
clickType = Click.FLAG;
}
myGame.pressed(new Move(new Location(row,col), clickType));
}
}
// Listens for reset option to be clicked
private class ResetListener implements ActionListener
{
// Instance Variables
Component uiWindow; // the Component is needed in order to display the JOptionPane
// Constructor
public ResetListener(Component window){
uiWindow = window;
}
public void actionPerformed(ActionEvent e){
// displays popup window, asking user if they want to restart the game
int response = JOptionPane.showConfirmDialog(uiWindow,"Are you sure you want to restart?", "Restart Game", JOptionPane.YES_NO_OPTION);
if(response == JOptionPane.YES_OPTION){ myGame.resetGame(); }
}
}
}