Revampled MainFrame layout to improve appearance/usability when the number of tiles is very large or small.

Fixed instantiation where a new MouseListener was used to each tile - now only one is used for all Tiles.
Fixed issue where the MouseListener was being added to each tile twice.
This commit is contained in:
Woody Folsom
2012-04-14 12:02:17 -04:00
parent 9619f9a96d
commit 74b8eb4622
7 changed files with 154 additions and 222 deletions

View File

@@ -7,18 +7,17 @@ import java.awt.event.MouseWheelListener;
import model.HumanPlayer;
import view.BoardPanel;
import view.Tile;
import view.TileSelectionPanel;
public class BoardPanelMouseListener implements MouseListener, MouseWheelListener {
private final BoardPanel boardPanel;
private static int clickNum = 0;
private final HumanPlayer humanPlayer;
private final TileSelectionPanel tsp;
public BoardPanelMouseListener(BoardPanel boardPanel, TileSelectionPanel tsp, HumanPlayer humanPlayer) {
public BoardPanelMouseListener(TileSelectionPanel tsp, HumanPlayer humanPlayer) {
this.humanPlayer = humanPlayer;
this.boardPanel = boardPanel;
this.tsp = tsp;
}
@@ -26,7 +25,7 @@ public class BoardPanelMouseListener implements MouseListener, MouseWheelListene
public void mouseClicked(MouseEvent e) {
Tile tile = (Tile) e.getComponent();
humanPlayer.setCell(tile.getRow(), tile.getCol());
boardPanel.updateIcons();
System.out.println("mouseClicked() " + (clickNum++));
}
@Override

View File

@@ -8,8 +8,8 @@ public class Board {
BLUE, GREEN, NONE, RED, YELLOW
}
public static final int NUM_COLS = 6;
public static final int NUM_ROWS = 6;
public static final int NUM_COLS = 5;
public static final int NUM_ROWS = 5;
public static final int ROW_REMOVAL_SIZE = 3;
private final TileColor[][] board;

View File

@@ -1,42 +1,23 @@
package model;
import view.BoardPanel;
import view.MessagePanel;
import model.Board.TileColor;
public class Referee {
public class Referee implements Runnable {
public enum Message {
COM_TURN {
@Override
public String toString() {
return "Waiting for the computer's move.";
}
},
GAME_OVER {
@Override
public String toString() {
return "Game over!";
}
},
NONE {
@Override
public String toString() {
return "";
}
},
PLAYER_TURN {
@Override
public String toString() {
return "Waiting for the player's move.";
}
}
}
public static final String COM_TURN = "Waiting for the computer's move.";
public static final String GAME_OVER = "Game over!";
public static final String PLAYER_TURN = "Waiting for the player's move.";
private final Board board;
private final HumanPlayer humanPlayer = new HumanPlayer();
private final Player cc;
private boolean playerTurn;
private BoardPanel boardPanel;
private int score = 0;
private MessagePanel messagePanel;
public Referee() {
board = new Board();
@@ -44,48 +25,61 @@ public class Referee {
playerTurn = true;
}
public void doSomething() {
if (playerTurn && humanPlayer.isReady()) {
Move mv = humanPlayer.getMove(board);
if (board.getTile(mv.getCell().r, mv.getCell().c) == TileColor.NONE) {
playToken(humanPlayer.getMove(board));
@Override
public void run() {
int plies = 0;
while (!isOver()) {
if (playerTurn) {
boolean wasInterrupted = false;
while (!humanPlayer.isReady()) {
try {
Thread.sleep(250L);
} catch (InterruptedException ie) {
wasInterrupted = true;
}
}
if (wasInterrupted) {
System.out.println("Interrupted while waiting for human to move!");
} else {
Move mv = humanPlayer.getMove(board);
if (board.getTile(mv.getCell().r, mv.getCell().c) == TileColor.NONE) {
playToken(humanPlayer.getMove(board));
} else {
humanPlayer.denyMove();
}
}
} else {
humanPlayer.denyMove();
Move mv = cc.getMove(board);
playToken(mv);
}
messagePanel.updateMessage(getMessage());
boardPanel.updateIcons();
System.out.println("plies: " + plies++);
try {
Thread.sleep(1000L);
} catch (InterruptedException ie) {
System.out.println("Interrupted while waiting for human view ply!");
}
} else if (!playerTurn) {
Move mv = cc.getMove(board);
playToken(mv);
}
}
public Player getCom() {
public Player getComputerPlayer() {
return cc;
}
public String getMessage() {
if (isOver()) {
return Message.GAME_OVER.toString();
}
else if (isPlayersTurn()) {
return Message.PLAYER_TURN.toString();
}
else {
return Message.COM_TURN.toString();
}
}
public HumanPlayer getHumanPlayer() {
return humanPlayer;
}
public int getScore() {
return score;
}
public TileColor getTile(int r, int c) {
return board.getTile(r, c);
public String getMessage() {
if (isOver()) {
return GAME_OVER;
} else if (isPlayersTurn()) {
return PLAYER_TURN;
} else {
return COM_TURN;
}
}
public boolean isOver() {
@@ -100,26 +94,34 @@ public class Referee {
return true;
}
private boolean isPlayersTurn() {
return playerTurn;
}
public int getScore() {
return score;
}
public TileColor getTile(int r, int c) {
return board.getTile(r, c);
}
public void playToken(Move move) {
board.setTile(move.getCell(), move.getColor());
if (playerTurn) {
incrementScore();
score++;
}
incrementTurn();
}
private void incrementScore() {
score++;
}
private void incrementTurn() {
playerTurn = !playerTurn;
}
private boolean isPlayersTurn() {
return playerTurn;
public void setBoardPanel(BoardPanel boardPanel) {
this.boardPanel = boardPanel;
}
public void setMessagePanel(MessagePanel messagePanel) {
this.messagePanel = messagePanel;
}
}

View File

@@ -35,17 +35,15 @@ public class BoardPanel extends JPanel {
referee = ref;
setLayout(new GridLayout(Board.NUM_ROWS, Board.NUM_COLS));
BoardPanelMouseListener bpml = new BoardPanelMouseListener(this, tsp, referee.getHumanPlayer());
BoardPanelMouseListener bpml = new BoardPanelMouseListener(tsp,
referee.getHumanPlayer());
ImageIcon noneIcon = new ImageIcon(NONE_ICON);
for (int r = 0; r < Board.NUM_ROWS; r++) {
for (int c = 0; c < Board.NUM_COLS; c++) {
Tile tile = new Tile(noneIcon,r,c);
Tile tile = new Tile(noneIcon, r, c);
board[r][c] = tile;
tile.addMouseListener(bpml);
board[r][c].addMouseListener(bpml);
board[r][c].addMouseWheelListener(bpml);
add(board[r][c]);
}
}

View File

@@ -1,10 +1,11 @@
package view;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.BorderLayout;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import model.Referee;
@@ -12,90 +13,85 @@ public class MainFrame extends JFrame {
private static final long serialVersionUID = 1L;
private final Referee referee;
public static void main(String[] args) {
new MainFrame();
MainFrame mainFrame = new MainFrame();
mainFrame.playGame();
}
private final Referee game;
public MainFrame() {
super("Project 4");
game = new Referee();
super("CS8803 Project 4");
referee = new Referee();
init();
// Set up window.
setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
setResizable(false);
pack();
setLocationRelativeTo(null);
setVisible(true);
run();
pack();
}
private void init() {
// Create objects.
ScorePanel sp = new ScorePanel(game);
TileSelectionPanel tp = new TileSelectionPanel(game.getHumanPlayer());
BoardPanel bp = new BoardPanel(game,tp);
MessagePanel mp = new MessagePanel(game);
ScorePanel sp = new ScorePanel(referee);
TileSelectionPanel tp = new TileSelectionPanel(referee.getHumanPlayer());
// Add stuff to panel.
GridBagLayout layout = new GridBagLayout();
GridBagConstraints con;
BoardPanel bp = new BoardPanel(referee,tp);
referee.setBoardPanel(bp);
con = new GridBagConstraints();
con.anchor = GridBagConstraints.WEST;
con.fill = GridBagConstraints.BOTH;
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 0;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(sp, con);
MessagePanel mp = new MessagePanel(referee);
referee.setMessagePanel(mp);
con = new GridBagConstraints();
con.anchor = GridBagConstraints.EAST;
con.fill = GridBagConstraints.BOTH;
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 1;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(mp, con);
//The outer wrapper allows the game board to be resized vertically.
JPanel vWrapper = new JPanel();
vWrapper.setLayout(new BoxLayout(vWrapper,BoxLayout.Y_AXIS));
con = new GridBagConstraints();
con.anchor = GridBagConstraints.NORTH;
con.fill = GridBagConstraints.BOTH;
con.gridwidth = 2;
con.gridx = 0;
con.gridy = 1;
layout.setConstraints(bp, con);
//The inner wrappers allow each sub-panel to be independently resized horizontally.
JPanel hWrapperTop = new JPanel();
hWrapperTop.setLayout(new BoxLayout(hWrapperTop,BoxLayout.X_AXIS));
JPanel hWrapperMid = new JPanel();
hWrapperMid.setLayout(new BoxLayout(hWrapperMid,BoxLayout.X_AXIS));
JPanel hWrapperBottom = new JPanel();
hWrapperBottom.setLayout(new BorderLayout());
con = new GridBagConstraints();
con.anchor = GridBagConstraints.NORTH;
con.fill = GridBagConstraints.BOTH;
con.gridwidth = 2;
con.gridx = 0;
con.gridy = 2;
con.insets = new Insets(10, 0, 10, 0);
layout.setConstraints(tp, con);
//Top horizontal-box wrapper contains message panel, score panel
hWrapperTop.add(Box.createHorizontalGlue());
hWrapperTop.add(mp);
hWrapperTop.add(sp);
hWrapperTop.add(Box.createHorizontalGlue());
setLayout(layout);
add(sp);
add(mp);
add(bp);
add(tp);
//Mid horizontal box wrapper contains board panel
hWrapperMid.add(Box.createHorizontalGlue());
JPanel bpContainer = new JPanel();
bpContainer.add(bp);
hWrapperMid.add(bpContainer);
hWrapperMid.add(Box.createHorizontalGlue());
//Bottom horizontal box wrapper contains tile panel
hWrapperBottom.add(tp,BorderLayout.NORTH);
//the outter wrapper contains the 3 inner wrappers: top, mid, bottom
vWrapper.add(hWrapperTop);
vWrapper.add(hWrapperMid);
vWrapper.add(hWrapperBottom);
//The main JFrame contains a the outer (vertical) wrapper, in the center of a BorderLayout.
setLayout(new BorderLayout());
add(vWrapper,BorderLayout.CENTER);
//To ensure correct size, pre-populate the score and message panels with text.
sp.updateScore();
mp.updateMessage("Loading new game...");
pack();
//Finally, update the border to show the initially selected tile color.
tp.updateBorders();
}
private void run() {
while (!game.isOver()) {
game.doSomething();
}
private void playGame() {
new Thread(referee).start();
}
}

View File

@@ -10,18 +10,16 @@ public class MessagePanel extends JPanel {
private static final long serialVersionUID = 1L;
private final JLabel message = new JLabel();
private final Referee referee;
private final JLabel label = new JLabel(" ");
public MessagePanel(Referee ref) {
referee = ref;
add(message);
add(label);
}
public void updateMessage() {
public void updateMessage(final String message) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
message.setText(referee.getMessage());
label.setText(message);
}
});
}

View File

@@ -1,9 +1,7 @@
package view;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
@@ -73,69 +71,10 @@ public class TileSelectionPanel extends JPanel {
}
private void initLayout() {
GridBagLayout layout = new GridBagLayout();
GridBagConstraints con;
JLabel spacer1 = new JLabel();
JLabel spacer2 = new JLabel();
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 0;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(spacer1, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 1;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(blue, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 2;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(green, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 3;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(red, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 4;
con.gridy = 0;
con.insets = new Insets(5, 5, 5, 5);
con.weightx = 0;
layout.setConstraints(yellow, con);
con = new GridBagConstraints();
con.gridheight = 1;
con.gridwidth = 1;
con.gridx = 5;
con.gridy = 0;
con.weightx = 1;
layout.setConstraints(spacer2, con);
setLayout(layout);
add(spacer1);
setLayout(new FlowLayout());
add(blue);
add(green);
add(red);
add(yellow);
add(spacer2);
}
}