-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGUI.java
More file actions
147 lines (120 loc) · 4.45 KB
/
Copy pathGUI.java
File metadata and controls
147 lines (120 loc) · 4.45 KB
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
package amazons;
import ucb.gui2.TopLevel;
import ucb.gui2.LayoutSpec;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.concurrent.ArrayBlockingQueue;
/** The GUI controller for an Amazons board and buttons.
* @author Khang
*/
class GUI extends TopLevel implements View, Reporter {
/** Minimum size of board in pixels. */
private static final int MIN_SIZE = 500;
/** A new window with given TITLE providing a view of an Amazons board. */
GUI(String title) {
super(title, true);
addMenuButton("Game->Quit", this::quit);
addMenuButton("Settings->Seed", this::newSeed);
addMenuButton("Game->New", this::open);
addMenuButton("Game->Undo", this::undo);
addMenuRadioButton("Settings->Players->White Manual",
"White", true, this::setWhiteManual);
addMenuRadioButton("Settings->Players->White AI",
"White", false, this::setWhiteAI);
addMenuRadioButton("Settings->Players->Black Manual",
"Black", false, this::setBlackManual);
addMenuRadioButton("Settings->Players->Black AI",
"Black", true, this::setBlackAI);
_widget = new BoardWidget(_pendingCommands);
add(_widget,
new LayoutSpec("y", 1,
"height", 1,
"width", 3));
}
/** Response to "Quit" button click. */
private void quit(String dummy) {
_pendingCommands.offer("quit");
}
/** Pattern describing the 'seed' command's arguments. */
private static final Pattern SEED_PATN =
Pattern.compile("\\s*(-?\\d{1,18})\\s*$");
/** Response to "New" button click. */
private void open(String dummy) {
_pendingCommands.offer("new");
}
/** Undo button. */
private void undo(String dummy) {
_pendingCommands.offer("undo");
}
/** Undo button. */
private void setWhiteManual(String dummy) {
_pendingCommands.offer("manual white");
}
/** Undo button. */
private void setWhiteAI(String dummy) {
_pendingCommands.offer("auto white");
}
/** Undo button. */
private void setBlackManual(String dummy) {
_pendingCommands.offer("manual black");
}
/** Undo button. */
private void setBlackAI(String dummy) {
_pendingCommands.offer("auto black");
}
/** Response to "Seed" button click. */
private void newSeed(String dummy) {
String response =
getTextInput("Enter new random seed.",
"New seed", "plain", "");
if (response != null) {
Matcher mat = SEED_PATN.matcher(response);
if (mat.matches()) {
_pendingCommands.offer(String.format("seed %s", mat.group(1)));
} else {
showMessage("Enter an integral seed value.", "Error", "error");
}
}
}
/** Return the next command from our widget, waiting for it as necessary.
* The BoardWidget uses _pendingCommands to queue up moves that it
* receives. Thie class uses _pendingCommands to queue up commands that
* are generated by clicking on menu items. */
String readCommand() {
try {
_widget.setMoveCollection(true);
String cmnd = _pendingCommands.take();
_widget.setMoveCollection(false);
return cmnd;
} catch (InterruptedException excp) {
throw new Error("unexpected interrupt");
}
}
@Override
public void update(Board board) {
_widget.update(board);
}
@Override
public void reportError(String fmt, Object... args) {
showMessage(String.format(fmt, args), "Amazons Error", "error");
}
@Override
public void reportNote(String fmt, Object... args) {
showMessage(String.format(fmt, args), "Amazons Message", "information");
}
@Override
public void reportMove(Move unused) {
}
/** The board widget. */
private BoardWidget _widget;
/** Queue of pending commands resulting from menu clicks and moves on the
* board. We use a blocking queue because the responses to clicks
* on the board and on menus happen in parallel to the methods that
* call readCommand, which therefore needs to wait for clicks to happen. */
private ArrayBlockingQueue<String> _pendingCommands =
new ArrayBlockingQueue<>(5);
/**
* javadoc.
*/
private Board _board;
}