Java AWT/Swing essentials
Bugs are prone to exist throughout the entire lifetime of a project; it's not any easier starting a brand new project than it is maintaining a project that's been running 5 years. Today's bug resulted from a new pet project of mine, creating a Go game. I don't have any gameplay logic implemented yet--I've just been wrestling with getting things to display correctly in the first place.
I decided to write the game in Java, utilizing the Swing and AWT libraries to provide a nice and simple GUI. Here's the idea of what I wanted to have set up:
First off, make sure you establish the minimum, preferred, and maximum sizes of your various components. I decided to set these dimensions on my Board component. After setting these, you need to call pack() on your JFrame instance, or else nothing will really show up.
The next thing I ran into was making sure to set the default close operation on my JFrame. In the GoFrame constructor, I had to use this line of code:
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Without this line, the process running the program isn't stopped when you click the close button on the frame. You can also pick a different WindowConstant to insert some logic before the program closes.
For the third bug, there are two big code snippets that you'll need for context. Here is the code from Board.java that adds all the necessary GoPoints to fill the board:
Here is the paint() method I overrode in GoPoint:
After I got the board to show up, I wanted to test what the pieces would look like, so I added a mouse event listener, which called a particular setPointType() method. When I implemented it and clicked on a point, however, nothing really updated. Fortunately, I tried to resize the frame after clicking on a point, and the piece magically appeared. This led me to realize that I was missing an important line in the setPointType() method: repaint();
Calling repaint signals to the window manager that the point needs to be repainted. This alone was enough to make the points turn into nice black and white circles whenever they were clicked on.
I decided to write the game in Java, utilizing the Swing and AWT libraries to provide a nice and simple GUI. Here's the idea of what I wanted to have set up:
- Go.java holds the main class and simply manages the instance of my JFrame, extended by the GoFrame class.
- GoFrame.java extends JFrame and also doesn't do too much at the moment. It adds one JPanel as its only component. This JPanel uses a BorderLayout to organize the major sections of the app. For now, I just place the main game board in the center.
- Board.java extends JComponent and uses a GridLayout to contain a grid of Points.
- GoPoint.java extends JPanel and represents a single point (intersection) on the board. Most of the initial meat of the program is found in this class, including both overriding paint() and handling click events.
First off, make sure you establish the minimum, preferred, and maximum sizes of your various components. I decided to set these dimensions on my Board component. After setting these, you need to call pack() on your JFrame instance, or else nothing will really show up.
The next thing I ran into was making sure to set the default close operation on my JFrame. In the GoFrame constructor, I had to use this line of code:
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Without this line, the process running the program isn't stopped when you click the close button on the frame. You can also pick a different WindowConstant to insert some logic before the program closes.
For the third bug, there are two big code snippets that you'll need for context. Here is the code from Board.java that adds all the necessary GoPoints to fill the board:
private void reinstantiateBoard(){
boolean drawLeft, drawRight, drawTop, drawBottom;
board = new GoPoint[boardSize][];
for (int i = 0; i < boardSize; i++) {
drawTop = i != 0;
drawBottom = i != boardSize - 1;
board[i] = new GoPoint[boardSize];
GoPoint[] pointArray = new GoPoint[boardSize];
for (int j = 0; j < boardSize; j++) {
drawLeft = j != 0;
drawRight = j != boardSize - 1;
pointArray[j] = new GoPoint(GoPoint.Type.EMPTY, drawLeft, drawRight, drawTop, drawBottom);
pointArray[j].setPointSize((int)(getMinimumSize().getWidth() / boardSize));
}
board[i] = pointArray;
}
removeAll();
for (GoPoint[] goPoints : board) {
for (GoPoint goPoint : goPoints) {
add(goPoint);
}
}
}
Here is the paint() method I overrode in GoPoint:
@Override
public void paint(Graphics g){
g.setColor(BOARD_BG);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLACK);
if (drawLeftLine)
g.drawLine(0, halfPointSize, halfPointSize, halfPointSize);
if (drawTopLine)
g.drawLine(halfPointSize, 0, halfPointSize, halfPointSize);
if (drawRightLine)
g.drawLine(halfPointSize, halfPointSize, pointSize, halfPointSize);
if (drawBottomLine)
g.drawLine(halfPointSize, halfPointSize, halfPointSize, pointSize);
if (type == Type.BLACK){
g.setColor(Color.black);
g.fillOval(0, 0, pointSize, pointSize);
}
else if (type == Type.WHITE){
g.setColor(Color.white);
g.fillOval(0, 0, pointSize, pointSize);
}
}
In summary, this block paints a brown background, a crosshair for an intersection point, and a black or white circle if a piece is occupying the point. The crosshair logic uses the four if statements to allow for not drawing lines on the edges of the board. With this code alone, along with Go, GoFrame, and Board, I get a nice go board showing up on the screen.
After I got the board to show up, I wanted to test what the pieces would look like, so I added a mouse event listener, which called a particular setPointType() method. When I implemented it and clicked on a point, however, nothing really updated. Fortunately, I tried to resize the frame after clicking on a point, and the piece magically appeared. This led me to realize that I was missing an important line in the setPointType() method: repaint();
Calling repaint signals to the window manager that the point needs to be repainted. This alone was enough to make the points turn into nice black and white circles whenever they were clicked on.
Comments
Post a Comment