/****************
* Name: Koh Wei Jie
*
* Purpose of this file: To be the graphical user interface for the entire
* game.
*
****************/
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;
public class ChessGUI extends JFrame implements ActionListener, MouseListener, ItemListener, FocusListener{
private ChessController cc;
private boolean hasCc = false;
private String playerName;
private String challengerName;
private String currentlyChallenging;
private String opponentName;
private boolean isWhite;
private final String helpMessage = "To play, enter your name and the server's information, if the defaults are incorrect.\n"
+ "Next select an opponent to challenge in the drop-down box.\n"
+ "To resign, press the Resign button.\nTo propose a draw, press the Draw button."
;
private final String aboutMessage = "Windows Application Development Assignment\n April 2008 Semester\n School of InfoComm Technology\n Ngee Ann Polytechnic\n Author: Koh Wei Jie";
private JMenuBar menuBar;
private JMenu gameMenu;
private JMenuItem helpMenuItem;
private JMenuItem aboutMenuItem;
private JMenuItem resetMenuItem;
private JPanel gamePanel;
private JPanel chessBoardPanel;
private JPanel chatPanel;
private JPanel chatBottomPanel;
private JComponent chessboard;
private JTextArea chatTxtArea;
private JTextField chatInputTxtField;
private JButton chatSendBtn;
private JPanel connectPanel;
private JButton connectBtn;
private JTextField nameTxtField;
private JLabel nameLabel;
private JTextField hostnameTxtField;
private JLabel hostnameLabel;
private JTextField portTxtField;
private JLabel portLabel;
private JPanel messagePanel;
private JLabel messageLabel;
private JPanel splashPanel;
private JPanel gameControlPanel;
private JButton resignBtn;
private JButton drawBtn;
//private JButton resetBtn;
private JPanel gameroomPanel;
private JLabel gameroomLabel;
private JComboBox gameroomCombo;
private JButton gameroomPlayBtn;
private JButton acceptChallengeBtn;
private JButton rejectChallengeBtn;
private JButton resignYesBtn = new JButton("Yes");
private JButton resignNoBtn = new JButton("No");
private JLabel resignLbl = new JLabel("Resign?");
private JButton drawAcceptBtn = new JButton("Accept");
private JButton drawRejectBtn = new JButton("Reject");
private JLabel oppDrawLabel = new JLabel("Your opponent proposed a draw. Do you accept this?");
private JButton drawYesBtn = new JButton("Yes");
private JButton drawNoBtn = new JButton("No");
private Dimension topControlPanelSize;
public ChessGUI(String title, int port, String host){
addMenus();
this.topControlPanelSize = new Dimension(700, 40);
//Chatarea
JPanel chatLblAndTxt = new JPanel(new BorderLayout());
this.chatTxtArea = new JTextArea(20, 20);
chatLblAndTxt.add(new JLabel("Chat"), BorderLayout.NORTH);
chatLblAndTxt.add(new JScrollPane(this.chatTxtArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER), BorderLayout.SOUTH);
this.chatInputTxtField = new JTextField(15);
this.chatSendBtn = new JButton("Send");
this.chatBottomPanel = new JPanel(new FlowLayout());
this.chatBottomPanel.add(this.chatInputTxtField);
this.chatBottomPanel.add(this.chatSendBtn);
this.chatPanel = new JPanel(new BorderLayout());
this.chatPanel.add(chatLblAndTxt);
this.chatPanel.add(this.chatBottomPanel, BorderLayout.SOUTH);
//----------------
//chat + board
this.gamePanel = new JPanel();
//this.chessboard = new Chessboard(false);
//----------------
//splash screen panel
this.splashPanel = new FixedSizeJPanel(660, 400){
public void paint(Graphics g){
ImageIcon splashimg = new ImageIcon("images/splash/splash.png");
g.drawImage(splashimg.getImage(), -20, 0, 660, 400, this);
}
};
toggleGamePanel(false);
//---------------
//messages
this.messagePanel = new FixedSizeJPanel(700, 30);
this.messagePanel.setLayout(new FlowLayout(FlowLayout.LEFT));
this.messageLabel = new JLabel();
this.messagePanel.add(this.messageLabel);
//----------------
//connection options
this.connectPanel = new FixedSizeJPanel(this.topControlPanelSize);
this.hostnameTxtField = new JTextField(10);
this.hostnameTxtField.setText(host);
this.hostnameLabel = new JLabel("Connect to");
this.portLabel = new JLabel("Port");
this.portTxtField = new JTextField(10);
this.connectBtn = new JButton("Connect");
this.portTxtField.setText(Integer.toString(port));
this.nameLabel = new JLabel("Your Name:");
this.nameTxtField = new JTextField(10);
this.connectPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
this.connectPanel.add(this.nameLabel);
this.connectPanel.add(this.nameTxtField);
this.connectPanel.add(this.hostnameLabel);
this.connectPanel.add(this.hostnameTxtField);
this.connectPanel.add(this.portLabel);
this.connectPanel.add(this.portTxtField);
this.connectPanel.add(this.connectBtn);
//----------------
//select opponent
this.gameroomPanel = new FixedSizeJPanel(630, (int)this.topControlPanelSize.getHeight());
this.gameroomPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
this.gameroomLabel = new JLabel("Select an opponent");
this.gameroomCombo = new JComboBox();
this.gameroomCombo.addItem("");
this.gameroomPlayBtn = new JButton("Play");
this.gameroomPanel.add(this.gameroomLabel);
this.gameroomPanel.add(this.gameroomCombo);
//----------------
//game control panel
this.gameControlPanel = new FixedSizeJPanel(this.topControlPanelSize);
this.gameControlPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
this.resignBtn = new JButton("Resign");
this.drawBtn = new JButton("Draw");
//this.resetBtn = new JButton("Reset");
this.gameControlPanel.add(this.resignBtn);
this.gameControlPanel.add(this.drawBtn);
//this.gameControlPanel.add(this.resetBtn);
//----------------
this.acceptChallengeBtn = new JButton("Accept");
this.rejectChallengeBtn = new JButton("Reject");
Container c = this.getContentPane();
c.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
setupConnectPanel();
addActionListeners();
this.setSize(700, 600);
this.setTitle(title);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
setMessage("Enter you name and connection details to begin.");
this.chessboard = new Chessboard(true, this.cc);
toggleGamePanel(true);
}
public void setMessage(String text){
this.messageLabel.setText(text);
}
public void getNewName(){
setupConnectPanel();
}
public void addMenus(){
this.menuBar = new JMenuBar();
this.gameMenu = new JMenu("Game");
//add the menus to the menubar
this.aboutMenuItem = new JMenuItem("About");
this.resetMenuItem = new JMenuItem("Reset");
this.helpMenuItem = new JMenuItem("Help");
this.gameMenu.add(this.aboutMenuItem);
this.gameMenu.add(this.resetMenuItem);
this.gameMenu.add(this.helpMenuItem);
this.menuBar.add(this.gameMenu);
this.setJMenuBar(this.menuBar);
}
public void addActionListeners(){
this.aboutMenuItem.addActionListener(this);
this.helpMenuItem.addActionListener(this);
this.resetMenuItem.addActionListener(this);
this.chatSendBtn.addActionListener(this);
this.chatInputTxtField.addActionListener(this);
this.connectBtn.addActionListener(this);
this.resignBtn.addActionListener(this);
this.drawBtn.addActionListener(this);
this.resignYesBtn.addActionListener(this);
this.resignNoBtn.addActionListener(this);
this.drawAcceptBtn.addActionListener(this);
this.drawRejectBtn.addActionListener(this);
this.drawYesBtn.addActionListener(this);
this.drawNoBtn.addActionListener(this);
this.gameroomPlayBtn.addActionListener(this);
this.nameTxtField.addActionListener(this);
this.gameroomCombo.addItemListener(this);
this.acceptChallengeBtn.addActionListener(this);
this.rejectChallengeBtn.addActionListener(this);
this.hostnameTxtField.addMouseListener(this);
this.portTxtField.addMouseListener(this);
this.hostnameTxtField.addFocusListener(this);
this.portTxtField.addFocusListener(this);
}
public void itemStateChanged(ItemEvent e){
if (e.getSource().equals(this.gameroomCombo)){
String opponentName = (String)this.gameroomCombo.getSelectedItem();
try{
if (opponentName.length() != 0 && !opponentName.equals(this.currentlyChallenging)){
this.cc.guiChallengeOpponent(opponentName);
this.currentlyChallenging = opponentName;
resetMessagePanel();
this.setMessage("Awaiting confirmation from " + opponentName + ".");
}
else{
return;
}
}
catch (NullPointerException npe){
//quirk. apparently the itemStateChanged event is fired
//every time the contents of the combobox are changed.
}
}
}
public void actionPerformed(ActionEvent e){
if (e.getSource().equals(this.connectBtn) || e.getSource().equals(this.nameTxtField)){
this.connect();
}
else if (e.getSource().equals(this.acceptChallengeBtn)){
this.cc.guiHandleChallenge(this.challengerName, true);
}
else if (e.getSource().equals(this.rejectChallengeBtn)){
this.rejectChallenge();
this.cc.guiHandleChallenge(this.challengerName, false);
this.challengerName = null;
}
else if (e.getSource().equals(this.chatSendBtn) || e.getSource().equals(this.chatInputTxtField)){
sendChat();
//scroll down automatically
this.chatTxtArea.setCaretPosition(this.chatTxtArea.getText().length());
}
else if (e.getSource().equals(this.resignBtn)){
resetMessagePanel();
this.setMessage("Resign?");
this.messagePanel.add(this.resignYesBtn);
this.messagePanel.add(this.resignNoBtn);
}
else if (e.getSource().equals(resignYesBtn)){
resign();
this.cc.resign();
}
else if (e.getSource().equals(resignNoBtn)){
resetMessagePanel();
setMessage("");
}
else if (e.getSource().equals(this.resetMenuItem)){
resign();
this.cc.resign();
}
else if (e.getSource().equals(this.drawBtn)){
resetMessagePanel();
this.setMessage("Draw?");
this.messagePanel.add(this.drawYesBtn);
this.messagePanel.add(this.drawNoBtn);
}
else if (e.getSource().equals(this.drawYesBtn)){
proposeDraw();
resetMessagePanel();
}
else if (e.getSource().equals(this.drawNoBtn)){
resetMessagePanel();
setMessage("");
}
else if (e.getSource().equals(this.drawAcceptBtn)){
acceptDraw();
}
else if (e.getSource().equals(this.drawRejectBtn)){
rejectDraw();
resetMessagePanel();
}
else if (e.getSource().equals(this.helpMenuItem)){
JOptionPane.showMessageDialog(
null,
this.helpMessage,
"Help",
JOptionPane.PLAIN_MESSAGE
);
}
else if (e.getSource().equals(this.aboutMenuItem)){
JOptionPane.showMessageDialog(
null,
this.aboutMessage,
"Help",
JOptionPane.PLAIN_MESSAGE
);
}
}
public void iWin(){
this.setMessage("You win!");
}
public void stalemate(){
this.setMessage("Stalemate.");
}
public void iLose(){
this.setMessage("You lose!");
}
public void checked(){
this.setMessage("You are under check.");
}
public void proposeDraw(){
this.cc.proposeDraw();
}
public void acceptDraw(){
this.cc.acceptDraw();
resetAfterResignOrDraw();
}
public void rejectDraw(){
this.cc.rejectDraw();
}
public void promoteOpp(int promoteTo, int xPos){
((Chessboard)this.chessboard).promoteOpp(promoteTo, xPos);
}
public void resetAfterResignOrDraw(){
this.getContentPane().remove(this.gameControlPanel);
this.getContentPane().remove(this.messagePanel);
this.getContentPane().remove(this.gamePanel);
this.gameroomPanel.setVisible(true);
this.gameroomLabel.setVisible(true);
this.gameroomCombo.setVisible(true);
resetMessagePanel();
this.setMessage("You have been connected. Please select an opponent.");
this.getContentPane().add(this.gameroomPanel);
this.getContentPane().add(this.messagePanel);
this.getContentPane().add(this.splashPanel);
this.repaint();
this.currentlyChallenging = "";
}
public void opponentProposesDraw(){
this.messagePanel.removeAll();
this.messagePanel.add(this.oppDrawLabel);
this.messagePanel.add(this.drawAcceptBtn);
this.messagePanel.add(this.drawRejectBtn);
this.repaint();
}
public void opponentAcceptsDraw(){
resetAfterResignOrDraw();
}
public void opponentRejectsDraw(){
resetMessagePanel();
}
public void resign(){
resetAfterResignOrDraw();
}
public void sendChat(){
String msg = this.chatInputTxtField.getText().trim();
if (msg.length() == 0){
return;
}
this.cc.sendChat(msg);
this.chatInputTxtField.setText("");
this.chatTxtArea.append(this.playerName + ": " + msg + "\n");
}
public void displayChat(String msg){
this.chatTxtArea.append(this.opponentName + ": " + msg + "\n");
}
public void promptAcceptChallenge(String challenger){
this.setMessage(challenger + " would like to play a game with you.");
this.challengerName = challenger;
this.messagePanel.add(this.acceptChallengeBtn);
this.messagePanel.add(this.rejectChallengeBtn);
this.repaint();
}
public void rejectChallenge(){
this.messagePanel.removeAll();
this.messagePanel.add(messageLabel);
this.setMessage("Challenge rejected.");
this.repaint();
}
public void opponentHasRejected(){
this.messagePanel.removeAll();
this.messagePanel.add(messageLabel);
this.setMessage("Your offer has been rejected.");
}
public void oppDisconnected(String who){
toggleGamePanel(false);
setMessage("The opponent disconnected.");
}
public void challengeAccepted(){
this.setMessage("accepted");
}
public void connect(){
if (checkConnDetails()){
if (!this.hasCc){
try{
this.cc = new ChessController(this.hostnameTxtField.getText(),
Integer.valueOf(this.portTxtField.getText()),
this);
}
catch (NullPointerException npe){
this.setMessage("The server is not running.");
return;
}
this.hasCc = true;
}
String name = this.nameTxtField.getText().trim();
if (!this.cc.guiSendName(name)){
this.setMessage("This name has been taken by another player. Please use another name.");
this.nameTxtField.selectAll();
return;
}
else{
this.playerName = name;
}
setupGameroomPanel();
this.setTitle("Chess- " + this.playerName);
this.setMessage("You have been connected. Please select an opponent..");
this.cc.guiConnected();
}
else{
//invalid input
this.setMessage("Please enter a name of no more than 20 characters, the server's address and the port number.");
}
}
public void resetMessagePanel(){
this.messagePanel.removeAll();
this.messagePanel.add(this.messageLabel);
this.repaint();
}
public void handleRejection(String opponentName){
resetMessagePanel();
setMessage(opponentName + " rejected the request.");
this.currentlyChallenging = null;
}
public void startGame(boolean isWhite, String opponentName){
this.isWhite = isWhite;
this.opponentName = opponentName;
resetMessagePanel();
String side;
if (isWhite){
side = "white";
}
else{
side = "black";
}
setMessage("You are on " + side + ", playing against " + opponentName + ". Have fun!");
this.chessboard = new Chessboard(isWhite, this.cc);
setupGameControlPanel();
toggleGamePanel(true);
this.getContentPane().remove(this.splashPanel);
}
public char resolveX(int x){
char[] characters = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'};
return characters[x];
}
public char resolveY(int y){
return Integer.toString(8 -y).charAt(0);
}
public void selfMovesPiece(int fromX, int fromY, int toX, int toY){
String side;
if (this.isWhite){
side = "White";
}
else{
side = "Black";
}
this.setMessage("(You are on " + side + ") You moved from " + resolveX(fromX) + resolveY(fromY) + " to " + resolveX(toX) + resolveY(toY) + ".");
}
public void movePiece(int fromX, int fromY, int toX, int toY){
((Chessboard)this.chessboard).movePiece(fromX, fromY, toX, toY);
this.setMessage(this.opponentName + " moved from " + resolveX(fromX) + resolveY(fromY) + " to " + resolveX(toX) + resolveY(toY) + ".");
}
public void updateNames(Vector<String> names){
if (!this.gameroomCombo.isPopupVisible()){
try{
this.gameroomCombo.removeAllItems();
}
catch (NullPointerException npe){
}
this.gameroomCombo.addItem("");
for (String n : names){
if (!n.equals(this.playerName)){
this.gameroomCombo.addItem(n);
}
}
}
this.repaint();
}
public void toggleGamePanel(boolean play){
this.gamePanel.removeAll();
if (play){
this.gamePanel.add(this.chessboard);
this.gamePanel.add(this.chatPanel);
}
else{
gamePanel.add(this.splashPanel);
}
}
public void setupConnectPanel(){
this.getContentPane().removeAll();
this.getContentPane().add(this.connectPanel);
this.getContentPane().add(this.messagePanel);
this.getContentPane().add(this.gamePanel);
}
public void setupGameArea(){
this.getContentPane().add(this.messagePanel);
this.getContentPane().add(this.gamePanel);
}
public void setupGameroomPanel(){
this.connectPanel.setVisible(false);
this.getContentPane().removeAll();
this.getContentPane().add(this.gameroomPanel);
setupGameArea();
}
public void setupGameControlPanel(){
this.gameroomPanel.setVisible(false);
this.connectPanel.setVisible(false);
this.getContentPane().remove(this.gamePanel);
this.getContentPane().remove(this.messagePanel);
this.getContentPane().add(this.gameControlPanel);
setupGameArea();
}
public boolean checkConnDetails(){
String name = this.nameTxtField.getText().trim();
String host = this.hostnameTxtField.getText().trim();
String port = this.portTxtField.getText().trim();
if (name.length() == 0 || name.length() > 20 || host.length() == 0 || port.length() == 0){
return false;
}
return true;
}
public void selectOnEvent(ComponentEvent e){
if (e.getSource().equals(this.hostnameTxtField)){
this.hostnameTxtField.selectAll();
}
else if (e.getSource().equals(this.portTxtField)){
this.portTxtField.selectAll();
}
}
public void focusGained(FocusEvent e){
selectOnEvent(e);
}
public void mouseClicked(MouseEvent e){
selectOnEvent(e);
}
public void focusLost(FocusEvent e){
selectOnEvent(e);
}
public void mouseEntered(MouseEvent e){ }
public void mouseExited(MouseEvent e){ }
public void mouseReleased(MouseEvent e){ }
public void mousePressed(MouseEvent e){ }
}