-
Notifications
You must be signed in to change notification settings - Fork 0
/
Canvas.java
208 lines (170 loc) · 6.88 KB
/
Canvas.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
/**
This class is for painting a canvas (grid) for the game. It uses a 2D array of Color object to represent the grid.
Written jointly by all of us.
*/
import java.awt.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
public class Canvas extends JPanel{
private int rows; // The number of rows for the grid.
private int columns; // The number of columns for the the grid.
private Color defaultColor;
private Color[][] grid;
private BufferedImage img; // The panel projected to the image, then the image
// //is copied to the screen
private Graphics graphic; // Graphics context for drawing to img
private boolean needsRedraw; // This is set to true when a change has occurred that
// changes the appearance of the panel.
/**Constructors*/
public Canvas(int rows, int columns, int blockWidth, int blockHeight, int borderWidth) {
this.rows = rows;
this.columns = columns;
grid = new Color[rows][columns];
//set default color and border color to be white and black respectively
defaultColor = Color.white;
Color borderColor=Color.black;
setBackground(defaultColor);
setOpaque(true);
setBorder(BorderFactory.createLineBorder(borderColor,borderWidth)); //the outside border is black
setPreferredSize(new Dimension(blockWidth*columns + 2*borderWidth, blockHeight*rows + 2*borderWidth)); //the overall size is the sum of total size + the size of borderlines
}
public Canvas(int rows, int columns, int blockWidth, int blockHeight) {
this(rows, columns, blockWidth, blockHeight,1);
}
//setters and getters
/**
* Return the defaultColor, which cannot be null.
*/
public Color getDefaultColor() {
return defaultColor;
}
//Set up the grid
public void setGridSize(int rows, int columns) {
if (rows > 0 && columns > 0) {
Color[][] newGrid = new Color[rows][columns];
for (int r = 0; r < rows; r++)
for (int c = 0; c < columns; c++)
newGrid[r][c] = grid[r][c];
grid = newGrid;
this.rows = rows;
this.columns = columns;
redraw();
}
}
/**
* Return the number of rows of rectangles in the grid.
*/
public int getRowCount() {
return rows;
}
/**
* Return the number of columns of rectangles in the grid.
*/
public int getColumnCount() {
return columns;
}
public Color getColor(int row, int col) {
if (row >=0 && row < rows && col >= 0 && col < columns)
return grid[row][col];
else
return null;
}
public void setColor(int row, int col, Color c) {
if (row >=0 && row < rows && col >= 0 && col < columns) {
grid[row][col] = c;
drawSquare(row,col,true);
}
}
// fill every square in the canvas with a color
public void fill(Color c) {
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
grid[i][j] = c;
redraw();
}
//clear
public void clear() {
fill(null);
}
//clear only red squares
public void clearRed(){
for (int i = 0; i < rows; i++)
for (int j = 0; j < columns; j++)
if (grid[i][j] == Color.RED)
grid[i][j]=null;
redraw();
}
//repaint the cancas
final public void redraw() {
needsRedraw = true;
repaint();
}
/**
* Turn the x-coordinate of point on the panel into the position of x on the grid
* @return -1 if the x coordinate is outside of the grid
*/
public int xCoordToColumnNumber(int x) {
//get the x,y coordinate of the JPanel (container)
Insets insets = getInsets();
if (x < insets.left)
return -1; // outside of the container
double colWidth = (double)(getWidth()-insets.left-insets.right) / columns; //the width of a column corresponding to the container
int col = (int)( (x-insets.left) / colWidth); //the corresponding col num of the point on the
//Color[][] grid converted from a position on the container
if (col >= columns)
return columns; //if outside of COlor[][] grid, return the righter most column number
else
return col;
}
/**
* Turn the y-coordinate of point on the panel into the position of x on the grid
* @return -1 if the y coordinate is outside of the grid
*/
public int yCoordToRowNumber(int y) {
Insets insets = getInsets();
if (y < insets.top)
return -1;// outside of the container
double rowHeight = (double)(getHeight()-insets.top-insets.bottom) / rows;//the eight of a row corresponding to the container
int row = (int)( (y-insets.top) / rowHeight);//the corresponding row num of the point on the
//Color[][] grid converted from a position on the container
if (row >= rows)
return rows;//if outside of COlor[][] grid, return the bottom row number
else
return row;
}
//overwritten from Java API to make the methods work
public void paintComponent(Graphics g) {
super.paintComponent(g);
synchronized(this) {
if ( (img == null) || img.getWidth() != getWidth() || img.getHeight() != getHeight() ) {
img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
graphic = img.getGraphics();
needsRedraw = true;
}
}
if (needsRedraw) {
for (int r = 0; r < rows; r++)
for (int c = 0; c < columns; c++)
drawSquare(r,c,false);
needsRedraw = false;
}
g.drawImage(img,0,0,null);
}
//overwritten from Java API to make the methods work
synchronized private void drawSquare(int row, int col, boolean callRepaint) {
Insets insets = getInsets();
double rowHeight = (double)(getHeight()-insets.left-insets.right) / rows;
double colWidth = (double)(getWidth()-insets.top-insets.bottom) / columns;
int xOffset = insets.left;
int yOffset = insets.top;
int y = yOffset + (int)Math.round(rowHeight*row);
int h = Math.max(1, (int)Math.round(rowHeight*(row+1))+yOffset - y);
int x = xOffset + (int)Math.round(colWidth*col);
int w = Math.max(1, (int)Math.round(colWidth*(col+1))+xOffset - x);
Color c = grid[row][col];
graphic.setColor( (c == null)? defaultColor : c );
graphic.fillRect(x,y,w,h);
if (callRepaint)
repaint(x,y,w,h);
}
}