package playerWindow; import java.awt.*; import java.awt.event.*; import java.util.*; /** * PlayerWindow - a graphical interface which supports playing * five-on-a-row on a 12x12 board. PlayerWindow offers 6 methods to * manipulate the appearance and the function of the PlayerWindow (see * below). PlayerWindow also emits the PlayerWindowEvent, which a * Player implementation must subscribe to in order to receive * messages from the PlayerWindow (and thereby the actions of the * player). Such a Player implementation MUST implement the * PlayerWindowListener interface. See the documentation of * PlayerWindowEvent and PlayerWindowListener. **/ public class PlayerWindow extends Frame { /** * placeChecker - draws a new checker of the color c in the given * x,y-spot. All colors are accepted, but only black and white * makes sense. * * @author I. Theiss 19990908 **/ public void placeChecker(Color c, int x, int y) { Board.update(c,x,y); Graphics g = canvas.getGraphics(); Board.clip(g); canvas.paint(g); g.dispose(); } /** * message - writes the string s into the message square of the * board, the old message is erased * * @author I. Theiss 19990908 **/ public void message(String s) { Message.setMessage(s); Graphics g = canvas.getGraphics(); Message.clip(g); canvas.paint(g); g.dispose(); } /** * setCheckerColor - sets the color of this player to the color c, * and the color of the opponent to the opposite. All colors are * accepted, but only black and white makes sense. * * @author I. Theiss 19990908 **/ public void setCheckerColor(Color c) { if (c == Color.white) CheckerColor.setColors(c, Color.black); else CheckerColor.setColors(c, Color.white); Graphics g = canvas.getGraphics(); CheckerColor.clip(g); canvas.paint(g); g.dispose(); } /** * disableBoard - lets the board part of the window ignore mouse * clicks. The traffic light is set to red to indicate the board * being disabled. This should be used while waiting for the * server, another player and while waiting for turn. * * @author I. Theiss 19990908 **/ public void disableBoard() { boardDisabled = true; TrafficLight.changeState(TrafficLight.RED); Graphics g = canvas.getGraphics(); TrafficLight.clip(g); canvas.paint(g); g.dispose(); } /** * enableBoard - lets the board part of the window respond to * mouse clicks. The traffic light is set to green to indicate * the board being enabled. This should be used when it is the * players turn. * * @author I. Theiss 19990908 **/ public void enableBoard() { boardDisabled = false; TrafficLight.changeState(TrafficLight.GREEN); Graphics g = canvas.getGraphics(); TrafficLight.clip(g); canvas.paint(g); g.dispose(); } /** * resetBoard - visually removes all checkers from the board. It * is not necessary to call resetBoard at window startup, but must * be used when a new game is started. * * @author I. Theiss 19990908 **/ public void resetBoard() { Board.initBoard(); Graphics g = canvas.getGraphics(); canvas.paint(g); g.dispose(); } /** * addPlayerWindowListener - subscribes to the PlayerWindowEvent. * * @author I. Theiss 19990908 **/ public synchronized void addPlayerWindowListener(PlayerWindowListener l) { Listeners.addElement(l); } /** * removePlayerWindowListener - unsubscribes from the * PlayerWindowEvent. * * @author I. Theiss 19990908 **/ public synchronized void removePlayerWindowListener(PlayerWindowListener l) { Listeners.removeElement(l); } /** * constructor - takes no arguments **/ public PlayerWindow() { try { canvas = new PlayerCanvas(this); this.add(canvas); canvas.addMouseListener(new mouseAdapter(this)); } catch (Exception e) { e.printStackTrace(); } ExitGame = new ExitGameArea(); NewGame = new NewGameArea(); Message = new MessageArea(); TrafficLight = new TrafficLightArea(); CheckerColor = new CheckerColorArea(); Board = new BoardArea(); pack(); setLocation(200, 200); show(); Graphics g = canvas.getGraphics(); canvas.paint(g); g.dispose(); } protected void mouseUp(MouseEvent e) { int x, y; x = e.getX(); y = e.getY(); if (ExitGame.clicked(x,y)) { notifyExitGame(); } else if (NewGame.clicked(x,y)) { notifyNewGame(); } else if (Board.clicked(x,y)) { if (boardDisabled) return; notifyBoardClicked(x,y); } } protected ExitGameArea ExitGame; protected NewGameArea NewGame; protected MessageArea Message; protected TrafficLightArea TrafficLight; protected CheckerColorArea CheckerColor; protected BoardArea Board; protected void notifyExitGame() { PlayerWindowEvent e = new PlayerWindowEvent(this); for (int i=0; i < Listeners.size(); i++) ((PlayerWindowListener)Listeners.elementAt(i)) .onExitGame(e); } protected void notifyNewGame() { PlayerWindowEvent e = new PlayerWindowEvent(this); for (int i=0; i < Listeners.size(); i++) ((PlayerWindowListener)Listeners.elementAt(i)) .onNewGame(e); } protected void notifyBoardClicked(int x, int y) { PlayerWindowEvent e = new PlayerWindowEvent(this, Board.clickedX(x), Board.clickedY(y)); for (int i=0; i < Listeners.size(); i++) ((PlayerWindowListener)Listeners.elementAt(i)) .onBoardClicked(e); } private PlayerCanvas canvas; private Vector Listeners = new Vector(); private PlayerWindowListener PI; private boolean boardDisabled = true; } class PlayerCanvas extends Canvas { public void paint(Graphics g) { PW.ExitGame.draw(g); PW.NewGame.draw(g); PW.Message.draw(g); PW.TrafficLight.draw(g); PW.CheckerColor.draw(g); PW.Board.draw(g); } public Dimension getPreferredSize() { return new Dimension(564,364); } protected PlayerCanvas(PlayerWindow pw) { super(); PW = pw; } private PlayerWindow PW; } class ClickableArea { protected String S; protected boolean clicked(int x, int y) { if (x > X && x < X+W && y > Y && y < Y+H) return true; else return false; } protected int X, Y, W, H; } class ButtonArea extends ClickableArea { protected void draw(Graphics g) { g.setColor(Color.yellow); g.fillRect(X+1,Y+1,W-1,H-1); g.setColor(Color.black); g.drawRect(X,Y,W,H); g.drawString(S,X+2,Y+14); } } class ExitGameArea extends ButtonArea { protected ExitGameArea() { X = 2; Y = 2; W = 196; H = 20; S = "Exit Game"; } } class NewGameArea extends ButtonArea { protected NewGameArea() { X = 2; Y = 24; W = 196; H = 20; S = "New Game"; } } class Square extends ClickableArea { protected Square(int x, int y, int w, int h) { X = x; Y = y; W = w; H = h; } } class BoardArea extends ClickableArea { protected BoardArea() { X = 202; Y = 2; H=360; W=360; initBoard(); } protected void initBoard() { for (int i=0; i < 12; i++) { for (int j=0; j < 12; j++) { board[i][j] = null; } } } protected void clip(Graphics g) { g.clipRect(X+updateX*30+1,Y+updateY*30+1,29,29); } protected void draw(Graphics g) { g.setColor(Color.gray); g.fillRect(X,Y,W,H); for (int i=0; i<13;i++) { g.setColor(Color.black); g.drawLine(X,Y+i*30,X+360,Y+i*30); g.drawLine(X+i*30,Y,X+i*30,Y+360); } for (int i=0; i<12; i++) { for (int j=0; j<12; j++) { if (board[i][j] != null) { g.setColor(board[i][j]); g.fillOval(X+i*30+2,Y+j*30+2,26,26); } } } } protected void update(Color c, int x, int y) { updateX = x; updateY = y; board[x][y] = c; } protected int clickedX(int x) { return (int)((x-X)/30); } protected int clickedY(int y) { return (int)((y-Y)/30); } protected int updateX, updateY; protected Color board[][] = new Color[12][12]; } class DrawableArea { protected void clip(Graphics g) { g.clipRect(X,Y,W,H); } protected void draw(Graphics g) { g.setColor(Color.black); g.drawRect(X,Y,W,H); g.setColor(Color.gray); g.fillRect(X+1,Y+1,W-1,H-1); } protected int X, Y, W, H; } class MessageArea extends DrawableArea { protected MessageArea () { X = 2; Y = 46; W = 196; H=40; } protected void setMessage(String m) { M = m; } protected void draw(Graphics g) { super.draw(g); g.setColor(Color.black); g.drawString(M, X+2, Y+14); } private String M="null"; } class CheckerColorArea extends DrawableArea { protected void setColors(Color me, Color opponent) { ME = me; OPPONENT = opponent; } protected CheckerColorArea () { X = 2; Y = 88; W = 196; H=34; } protected void draw(Graphics g) { super.draw(g); g.setColor(Color.black); g.drawString("ME:",X+2,Y+14); g.drawString("OPPONENT:",X+63,Y+14); if (ME != null) { g.setColor(ME); g.fillOval(X+27,Y+2,30,30); } else g.drawOval(X+27,Y+2,30,30); if (OPPONENT != null) { g.setColor(OPPONENT); g.fillOval(X+138,Y+2,30,30); } else g.drawOval(X+138,Y+2,30,30); } private Color ME = null, OPPONENT = null; } class TrafficLightArea extends DrawableArea { protected static int RED = 0, GREEN = 1; protected void changeState(int s) { state = s; } protected TrafficLightArea() { X = 82; Y = 191; W = 34; H=100; } protected void draw(Graphics g) { super.draw(g); if (state == RED) { g.setColor(new Color(0xf70000)); g.fillOval(X+2,Y+2,30,30); g.setColor(Color.black); g.drawOval(X+2,Y+2,30,30); g.setColor(new Color(0xaa6529)); g.fillOval(X+2,Y+34,30,30); g.setColor(new Color(0x3d6303)); g.fillOval(X+2,Y+66,30,30); } else { g.setColor(new Color(0x871b19)); g.fillOval(X+2,Y+2,30,30); g.setColor(new Color(0xaa6529)); g.fillOval(X+2,Y+34,30,30); g.setColor(new Color(0x30a306)); g.fillOval(X+2,Y+66,30,30); g.setColor(Color.black); g.drawOval(X+2,Y+66,30,30); } } private int state=RED; } class mouseAdapter extends java.awt.event.MouseAdapter { PlayerWindow adaptor; public mouseAdapter(PlayerWindow adaptor) { this.adaptor = adaptor; } public void mouseReleased(MouseEvent e) { adaptor.mouseUp(e); } }