Package client.frame

Source Code of client.frame.GameplayFrame$LeaderboardScrollListener

package client.frame;

import game.dice.Dice;
import game.gamesheet.GameSheet;
import general.statics.function.GUIFunctions;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Date;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;

import server.constants.CommandList;
import server.protocol.Message;
import client.Client;
import client.custom.DrawingPanel;
import client.custom.JCustomField;
import client.custom.JCustomPane;
import client.custom.JCustomPanel;
import client.frame.listener.InstructButtonListener;
import client.frame.listener.LeaveButtonListener;
import client.frame.timer.ActTimeCountdown;
import client.frame.timer.JLabelSubscriber;
import client.gui.Constants;
import client.model.GameSheetTableModel;
import client.model.GameSheetTitleTableModel;
/**
* The <code>GameplayFrame</code> class, a descendant of <code>YahtzeeFrame</code>, is the frame class for displaying the
* main gameplay screen of the Yahtzee game. Contains a huge pile of dynamic inputs and controls.
*
* @author Priidu Neemre
*/
public class GameplayFrame extends YahtzeeFrame{

  //Constants
  private static final long serialVersionUID = 00000001L;
  public static final int WINDOW_WIDTH = 900;
  public static final int WINDOW_HEIGHT = 600;
  public static final int DIE_ROLL_AREA_DIMENSION = 150;
  public static final int DIE_SAVE_AREA_HEIGHT = 200;
  public static final int DIE_SAVE_AREA_WIDTH = 10;
 
  public static final int SCORETABLE_HEIGHT = 315;
  public static final int SCORETABLE_ROW_WIDTH = 80;
  public static final int SCORETABLEHEADER_ROW_WIDTH = 160;

  public static final int INFO_AREA_HEIGHT = 220;
  public static final int INFO_AREA_WIDTH = 500;
 
  public static final int LEADER_AREA_HEIGHT = 250;
  public static final int LEADER_AREA_WIDTH = 120;
   
  //GENERAL GUI elements
  private JCustomPanel bgPanel;
  private DrawingPanel drawingPanel;
 
  //GENERAL MENU GUI elements (lower eastern corner)
  private JButton newGameBtn;
  private JButton instructionsBtn;
  private JButton leaveGameBtn;
  private JPanel generalButtonPanel;
  private JLabel txt_generalMenu;
  private JPanel generalButtonHeadingPanel;

  //PLAY MENU GUI elements (upper eastern corner)
  private JLabel txt_playMenu;
  private JPanel playHeadingPanel;
  private JButton rollDiceBtn;
  private JLabel txt_rollsLeft;
  private JLabel rollsLeftInd;
  private JPanel rollPanel;
 
  private JLabel txt_turnTimeLeft;
  private JLabelSubscriber turnTimerText;

  private JPanel turnTimePanel;

  private JButton skipTurnBtn;
  private JPanel skipPanel;
 
  //TURN/PLAYERINFO area elements (upper eastern corner)
  private JLabel txt_loggedIn;
  private JLabel playerNameInd;
  private JLabel txt_curRoller;
  private JLabel rollerNameInd;
  JPanel turnMenuPanel;
 
  //JTABLEes and their table model bases
  private GameSheetTableModel gameSheetGUI;
  private JTable scoreSheet;
  private GameSheetTitleTableModel gameSheetTitles;
  private JTable scoreSheetTitles;
  private JScrollPane containerPane;
 
  //CHAT/INFO area elements (for displaying in-game chat, server announcements etc.)
  private JTextArea logArea;
  private JScrollPane logAreaPane;
 
  private JButton btnSayText;
  private JTextField sayField;
 
  //LEADERBOARD elements (for displaying the all-time Hall-of-Fame scores)
  private JLabel txt_leaderArea;
  private JTextArea leaderArea;
  private JScrollPane leaderAreaPane;
  private JPanel leaderAreaPanel;
 
  //Pointers to crucial business-logic objects
  private Dice curGameDice;
  private GameSheet gameSheet;
 
  //Pointers to crucial technical objects
  private Client client;
   
  public GameplayFrame(Client client){
   
    this.curGameDice = client.getDice();
    this.gameSheet = client.getGameSheet();
    this.client = client;
   
    buildConfigureJFrame();
    buildConfigureMainContainers(curGameDice);
   
    buildConfigureTurnMenu();
    buildConfigurePlayMenuGUI(curGameDice);
    buildConfigureLeaderboardGUI();
    buildConfigureGeneralMenuGUI();
   
    buildConfigureJTable(gameSheet);
    buildConfigureLoggingArea();
   
    weldTogetherEasternMenus();
    updateGUIIndicators();
   
    this.setVisible(true);
 
 
  /**
   * Sets the desired properties for the <code>GameplayFrame</code> itself.
   */
  private void buildConfigureJFrame(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setLocation(350,150);
    this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    this.setTitle(FRAME_DEFAULT_TITLE);
    this.setLocationRelativeTo(null); //Align the JFrame to the center of the screen
  }
 
  /**
   * Instantiates variables and enforces properties in connection with the main containers of the frame.
   */
  private void buildConfigureMainContainers(Dice curGameDice){
   
    //Create the contentpane JPanel(bgPanel) of the frame, the root container for all following elements
    bgPanel = new JCustomPanel(new BorderLayout(), Constants.MAIN_BACKGROUND_IMAGE_PATH);
    bgPanel.setBorder(BorderFactory.createMatteBorder(1,1,1,1,Color.BLACK));
    setContentPane(bgPanel);
    //Create a panel for animation behaviour (drawingPanel) to display dice rolls etc.
    drawingPanel = new DrawingPanel(curGameDice);
    drawingPanel.addMouseListener(new ClickDiceListener());
    drawingPanel.setOpaque(false);
   
    getContentPane().add(drawingPanel);
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Turn menu" area.
   */
  private void buildConfigureTurnMenu(){
   
    txt_loggedIn = new JLabel("Logged in as:            ");
    txt_loggedIn.setFont(Constants.tahoma_mediumsmall_bold);
    txt_loggedIn.setForeground(Color.WHITE);
   
    playerNameInd = new JLabel("TurkWarrior");
    playerNameInd.setFont(Constants.tahoma_mediumsmall_bold);
    playerNameInd.setForeground(Color.RED);
   
    txt_curRoller = new JLabel("Currently rolling:       ");
    txt_curRoller.setFont(Constants.tahoma_mediumsmall_bold);
    txt_curRoller.setForeground(Color.WHITE);
   
    rollerNameInd = new JLabel("Metsamees123");
    rollerNameInd.setFont(Constants.tahoma_mediumsmall_bold);
    rollerNameInd.setForeground(Color.RED);
   
    turnMenuPanel = new JCustomPanel(new FlowLayout(FlowLayout.LEFT), Constants.REGULAR_TILE_IMAGE_PATH);
    turnMenuPanel.setPreferredSize(new Dimension(120, 78));
    turnMenuPanel.setBorder(BorderFactory.createMatteBorder(0, 1, 1, 0, Color.BLACK));
    turnMenuPanel.setOpaque(false);
   
    turnMenuPanel.add(txt_loggedIn);
    turnMenuPanel.add(playerNameInd);
    turnMenuPanel.add(txt_curRoller);
    turnMenuPanel.add(rollerNameInd);
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "General menu" area.
   */
  private void buildConfigureGeneralMenuGUI(){

    newGameBtn = new JButton("Join new game");
    newGameBtn.setPreferredSize(new Dimension(110, 22));
    newGameBtn.addActionListener(new JoinNewListener());
   
    instructionsBtn = new JButton("Instructions");
    instructionsBtn.setPreferredSize(new Dimension(110, 22));
    instructionsBtn.addActionListener(new InstructButtonListener());
   
    leaveGameBtn = new JButton("Leave game");
    leaveGameBtn.setPreferredSize(new Dimension(110, 22));
    leaveGameBtn.addActionListener(new LeaveButtonListener(client));
   
    generalButtonPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 2, 3), Constants.REGULAR_TILE_IMAGE_PATH);
    generalButtonPanel.setPreferredSize(new Dimension(120,190));
    generalButtonPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.BLACK));
    generalButtonPanel.setOpaque(false);
   
    generalButtonPanel.add(newGameBtn);
    generalButtonPanel.add(instructionsBtn);
    generalButtonPanel.add(leaveGameBtn);
   
    txt_generalMenu = new JLabel("General menu");
    txt_generalMenu.setFont(Constants.tahoma_medium_bold);
    txt_generalMenu.setForeground(Color.WHITE);
   
    generalButtonHeadingPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 2, 2), Constants.REGULAR_TILE_IMAGE_PATH);
    generalButtonHeadingPanel.setPreferredSize(new Dimension(120,18));
    generalButtonHeadingPanel.setOpaque(false);
    generalButtonHeadingPanel.add(txt_generalMenu);
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Leaderboard" area.
   */
  private void buildConfigureLeaderboardGUI(){
   
    txt_leaderArea = new JLabel("Hall of Fame (top 20)");
    txt_leaderArea.setFont(Constants.tahoma_mediumsmall_bold);
    txt_leaderArea.setForeground(Color.WHITE);
   
    leaderArea = new JTextArea();
    leaderArea.setLineWrap(true);
    leaderArea.setFont(Constants.tahoma_small_normal);
    leaderArea.setForeground(Color.WHITE);
    leaderArea.setEditable(false);
    leaderArea.setOpaque(false);
   
    leaderAreaPane = new JCustomPane(leaderArea, Constants.TEXTAREA_TILE_IMAGE_PATH);
    leaderAreaPane.setPreferredSize(new Dimension(LEADER_AREA_WIDTH - 3, LEADER_AREA_HEIGHT - 26));
    leaderAreaPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    leaderAreaPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    leaderAreaPane.getVerticalScrollBar().addAdjustmentListener(new LeaderboardScrollListener());
    leaderAreaPane.setOpaque(false);
    leaderAreaPane.getViewport().setOpaque(false);
   
    leaderAreaPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER,1,1), Constants.REGULAR_TILE_IMAGE_PATH);
    leaderAreaPanel.setPreferredSize(new Dimension(new Dimension(LEADER_AREA_WIDTH, LEADER_AREA_HEIGHT - 6)));
    leaderAreaPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, Color.BLACK));
    leaderAreaPanel.setOpaque(false);
   
    leaderAreaPanel.add(txt_leaderArea);
    leaderAreaPanel.add(leaderAreaPane);
    //for(int i = 0; i < 20; i++)leaderArea.append((i+1) + " turkWarrior666   " + (374 - i*3) + "\n");  //DEBUG INFO 
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Play menu" area.
   */
  private void buildConfigurePlayMenuGUI(Dice curGameDice){

    txt_playMenu = new JLabel("Play options");
    txt_playMenu.setFont(Constants.tahoma_medium_bold);
    txt_playMenu.setForeground(Color.WHITE);
   
    playHeadingPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 1, 2), Constants.REGULAR_TILE_IMAGE_PATH);
    playHeadingPanel.setPreferredSize(new Dimension(119,18));
    playHeadingPanel.setOpaque(false);
    playHeadingPanel.add(txt_playMenu);

    rollDiceBtn = new JButton("Roll");
    rollDiceBtn.setPreferredSize(new Dimension(110,22));
    rollDiceBtn.addActionListener(new RollActionListener());
   
    txt_rollsLeft = new JLabel("Rolls left:  ");
    txt_rollsLeft.setBorder(new EmptyBorder(4,0,0,0));
    txt_rollsLeft.setFont(Constants.tahoma_mediumsmall_bold);
    txt_rollsLeft.setForeground(Color.WHITE);
   
    rollsLeftInd = new JLabel("2");
    rollsLeftInd.setBorder(new EmptyBorder(4,0,0,0));
    rollsLeftInd.setFont(Constants.tahoma_mediumsmall_bold);
    rollsLeftInd.setForeground(Color.RED)
       
    rollPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 1, 2), Constants.REGULAR_TILE_IMAGE_PATH);
    rollPanel.setPreferredSize(new Dimension(119, 45));
    rollPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK));
    rollPanel.setOpaque(false)
   
    rollPanel.add(rollDiceBtn);
    rollPanel.add(txt_rollsLeft);
    rollPanel.add(rollsLeftInd);
   
    txt_turnTimeLeft = new JLabel("Turn time left:");
    txt_turnTimeLeft.setFont(Constants.tahoma_mediumsmall_bold);
    txt_turnTimeLeft.setForeground(Color.WHITE);
 
    turnTimerText = new JLabelSubscriber("03:00");
    turnTimerText.setFont(Constants.tahoma_mediumsmall_bold);
    turnTimerText.setForeground(Color.RED)
    client.setTurnTimer(new ActTimeCountdown(Client.TURN_TIME_MILLIS, Client.TIMEUNIT_MILLIS, client));
    client.getTurnTimer().addSubscriber(turnTimerText);

    turnTimePanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 10, 2), Constants.REGULAR_TILE_IMAGE_PATH);
    turnTimePanel.setPreferredSize(new Dimension(119, 33));
    turnTimePanel.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.BLACK));
    turnTimePanel.setOpaque(false);
   
    turnTimePanel.add(txt_turnTimeLeft);
    turnTimePanel.add(turnTimerText);
       
    skipTurnBtn = new JButton("Skip turn");
    skipTurnBtn.setPreferredSize(new Dimension(110, 22));
    skipTurnBtn.addActionListener(new SkipListener());

    skipPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 2, 2), Constants.REGULAR_TILE_IMAGE_PATH);
    skipPanel.setPreferredSize(new Dimension(119, 27));
    skipPanel.setOpaque(false);
    skipPanel.add(skipTurnBtn);
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Gamesheet" area.
   */
  private void buildConfigureJTable(GameSheet newSheet){
    //Create a JTable for displaying the scores, another JTable as a row header (combination names) and a JScrollPane
    //to hold the two
    gameSheetGUI = new GameSheetTableModel(newSheet);
    scoreSheet = new JTable(gameSheetGUI);
    scoreSheet.getTableHeader().setReorderingAllowed(false);
    scoreSheet.getTableHeader().setResizingAllowed(false);
    GUIFunctions.alignJTableContents(JLabel.CENTER, scoreSheet);
    scoreSheet.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    GUIFunctions.setAllJTableColumnWidths(scoreSheet, SCORETABLE_ROW_WIDTH);
    scoreSheet.addMouseListener(new ClickGamesheetListener());
   
    gameSheetTitles = new GameSheetTitleTableModel(newSheet);
    scoreSheetTitles = new JTable(gameSheetTitles);
    scoreSheetTitles.getTableHeader().setReorderingAllowed(false);
    scoreSheetTitles.getTableHeader().setResizingAllowed(false);
    GUIFunctions.alignJTableContents(JLabel.LEFT, scoreSheetTitles);
    scoreSheetTitles.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    GUIFunctions.setAllJTableColumnWidths(scoreSheetTitles, SCORETABLE_ROW_WIDTH*2);
    scoreSheetTitles.setAutoResizeMode(JTable.AUTO_RESIZE_NEXT_COLUMN);
    scoreSheetTitles.setPreferredScrollableViewportSize(new Dimension(SCORETABLE_ROW_WIDTH*2,
        SCORETABLE_HEIGHT));
   
    containerPane = new JScrollPane(scoreSheet);
    containerPane.setRowHeaderView(scoreSheetTitles);
    containerPane.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
   
    containerPane.setPreferredSize(new Dimension(newSheet.getNoOfPlayers()*SCORETABLE_ROW_WIDTH
        + SCORETABLEHEADER_ROW_WIDTH + 2, SCORETABLE_HEIGHT));
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Logging area" pane.
   */
  private void buildConfigureLoggingArea(){

    logArea = new JTextArea();
    logArea.setLineWrap(true);
    logArea.setWrapStyleWord(true);
    logArea.setEditable(false);
    logArea.setFont(Constants.tahoma_mediumsmall_normal);
    logArea.setForeground(Color.WHITE);
    logArea.setOpaque(false);

    logAreaPane = new JCustomPane(logArea, Constants.TEXTAREA_TILE_IMAGE_PATH);
    logAreaPane.setPreferredSize(new Dimension(INFO_AREA_WIDTH - 6, INFO_AREA_HEIGHT - 25));
    logAreaPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    logAreaPane.getVerticalScrollBar().addAdjustmentListener(new LogScrollListener());
    logAreaPane.setOpaque(false);
    logAreaPane.getViewport().setOpaque(false);
   
    btnSayText = new JButton("Say");
    btnSayText.setPreferredSize(new Dimension(50,20));
    btnSayText.addActionListener(new SayMessageListener());
   
    sayField = new JCustomField(Constants.TEXTAREA_TILE_IMAGE_PATH);
    sayField.setPreferredSize(new Dimension(INFO_AREA_WIDTH-58, 20));
    sayField.setFont(Constants.tahoma_mediumsmall_normal);
    sayField.setForeground(Color.WHITE);
    sayField.setCaretColor(Color.WHITE);
    sayField.setOpaque(false);
    sayField.addActionListener(new SayMessageListener());
   
    writeToLogArea("[" + new Date() + "]: Welcome to Yahtzee! If you want to say something to your fellow players, feel free to " +
        "us the chatbox provided below! We would also like to remind you, that to leave the current game, join a new game or " +
        "read the instructions and rules for the game, refer to the button menu on the lower right corner.\n");   
    //for(int i = 0; i < 100; i++){logArea.append("[" + new Date() + "]: Announcement " + i + "- The quick brown fox jumped over the crying 8-year-old molested by a catholic priest (must \"huumor\").\n");}  //DEBUG INFO
  }
 
  /**
   * Builds up and welds together the entire eastern side of the frame by the use of <code>JPanel</code>'s and <code>
   * GridBagLayout</code>. Adds the eastern side to the content pane of the frame.
   */
  private void weldTogetherEasternMenus(){

    JPanel easternPanel = new JPanel(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
   
      JPanel intEasternPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
      intEasternPanel.setPreferredSize(new Dimension(500, 570));
      intEasternPanel.setOpaque(false);
   
        JPanel upperIntEasternPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
        upperIntEasternPanel.setPreferredSize(new Dimension(500, 347));
        upperIntEasternPanel.setOpaque(false);
             
        upperIntEasternPanel.add(containerPane);   
       
      intEasternPanel.add(upperIntEasternPanel);
   
        JPanel lowerIntEasternPanel = new JCustomPanel(new FlowLayout(FlowLayout.CENTER, 2, 2), Constants.REGULAR_TILE_IMAGE_PATH);
        lowerIntEasternPanel.setPreferredSize(new Dimension(INFO_AREA_WIDTH, INFO_AREA_HEIGHT+3));
        lowerIntEasternPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, Color.BLACK));
        lowerIntEasternPanel.setOpaque(false)
         
        lowerIntEasternPanel.add(logAreaPane);
        lowerIntEasternPanel.add(sayField);
        lowerIntEasternPanel.add(btnSayText);
       
      intEasternPanel.add(lowerIntEasternPanel);
       
    c.fill = GridBagConstraints.VERTICAL;
    c.gridx = 0;
    c.gridy = 0;   
    easternPanel.add(intEasternPanel, c)
   
      JPanel extEasternPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
      extEasternPanel.setPreferredSize(new Dimension(120,570));

        JPanel mostUpperExtEasternPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        mostUpperExtEasternPanel.setPreferredSize(new Dimension(120, 82));
        mostUpperExtEasternPanel.setOpaque(false);
     
        mostUpperExtEasternPanel.add(turnMenuPanel);
     
      extEasternPanel.add(mostUpperExtEasternPanel);
       
        JPanel upperExtEasternPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        upperExtEasternPanel.setPreferredSize(new Dimension(120, 125));
        upperExtEasternPanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, Color.BLACK));
        upperExtEasternPanel.setOpaque(false);
       
        upperExtEasternPanel.add(playHeadingPanel);
        upperExtEasternPanel.add(rollPanel);
        upperExtEasternPanel.add(turnTimePanel);
        upperExtEasternPanel.add(skipPanel);
       
      extEasternPanel.add(upperExtEasternPanel);
         
        JPanel midExtEasternPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        midExtEasternPanel.setPreferredSize(new Dimension(LEADER_AREA_WIDTH, LEADER_AREA_HEIGHT));
        midExtEasternPanel.setBorder(new EmptyBorder(3, 0, 3, 0));
        midExtEasternPanel.setOpaque(false)
         
        midExtEasternPanel.add(leaderAreaPanel);
       
      extEasternPanel.add(midExtEasternPanel);

        JPanel lowerExtEasternPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        lowerExtEasternPanel.setPreferredSize(new Dimension(120, 113));
        lowerExtEasternPanel.setBorder(BorderFactory.createMatteBorder(1 ,0 ,0 ,0 ,Color.BLACK));
        lowerExtEasternPanel.setOpaque(false);
       
        lowerExtEasternPanel.add(generalButtonHeadingPanel);
        lowerExtEasternPanel.add(generalButtonPanel);
 
      extEasternPanel.add(lowerExtEasternPanel);   
      extEasternPanel.setOpaque(false);
   
    c.fill = GridBagConstraints.VERTICAL;
    c.gridx = 1;
    c.gridy = 0;
    easternPanel.add(extEasternPanel, c);

    getContentPane().add(easternPanel, BorderLayout.EAST);
    easternPanel.setOpaque(false);
  }

  @Override
  public void updateGUIIndicators(){
    //General GUI updates
    setTitle(FRAME_DEFAULT_TITLE + " - " + client.getClientName());
    playerNameInd.setText(client.getClientName());
    rollerNameInd.setText(client.getDice().getCurOwner());
    rollsLeftInd.setText("" + (Dice.ALLOWED_ROLLS - client.getDice().getTimesRolled()));
    leaderArea.setText(client.getLeaderboard().getAsString());
   
    //State-specific updates
    switch(client.getState()){
    case GAME_IN_PROGRESS:
        if(!(client.getDice().getCurOwner().equals(client.getClientName()))){  //Check if current players turn (FALSE)
          lockAllInputs();
      }else if(client.getDice().getCurOwner().equals(client.getClientName())){  //Check if current players turn (TRUE)
        if(client.getDice().getTimesRolled() == Dice.ALLOWED_ROLLS){  //Check if still has free rolls left (FALSE)
          rollDiceBtn.setEnabled(false);
          skipTurnBtn.setEnabled(true);
          scoreSheet.setEnabled(true);
        }else//Check if still has free rolls left (FALSE)
          rollDiceBtn.setEnabled(true);
          skipTurnBtn.setEnabled(true);
          scoreSheet.setEnabled(true);
        }
      }
      break;
    case GAME_FINISHED:
      lockAllInputs();
      break;
    default:
      break;
    }     
    this.repaint();
  }
 
  /**
   * Locks all the player-manipulatable inputs of the frame.
   */
  public void lockAllInputs(){
    rollDiceBtn.setEnabled(false);
    skipTurnBtn.setEnabled(false);
    scoreSheet.setEnabled(false);
    drawingPanel.setEnabled(false);
  }

  /**
   * Notifies the player about the end of the current game and transitions the client to the <code>GAME_FINISHED</code> state.
   * Displays a confirmation dialog asking if the player wants another game:  If "Yes" is chosen, the client is reloaded
   * with a restart. In any other case, the client is reloaded without a restart.
   */
  public void notifyGameFinished(){
    ArrayList<String> sortedResults = client.getGameSheet().getSortedResult(client.getClientName());
    client.fGameInProgressTOGameFinished();
    updateGUIForeign();   
    int decision = JOptionPane.showConfirmDialog(null,
        "Congratulations " + client.getClientName() + "! You earned the "
            + sortedResults.get(2) + ". place with a score of " + sortedResults.get(1) + "!\n"
            + "Would you like to play again?",
        "Game finished", JOptionPane.YES_NO_OPTION);
    if(decision == JOptionPane.YES_OPTION){
      dispose();
      client.reloadClient(Client.RELOAD_WITH_RESTART);
    }else if(decision == JOptionPane.NO_OPTION){
      client.reloadClient(Client.RELOAD_WITHOUT_RESTART);
    }
  }
 
  /**
   * Displays a notification, letting the player know that he/she made it to the Top 20 Hall of Fame.
   */
  public void notifyNewHighScore(){
    int clientIndex = client.getGameSheet().getClientIndex(client.getClientName());
   
    JOptionPane.showMessageDialog(null, "NEW HIGH SCORE! Congratulations!\nYou, " + client.getClientName() +
      ", have been added to the Top 20 Hall of Fame with a score of " +
        client.getGameSheet().getGameSheetContents().get(clientIndex).get(GameSheet.TOTAL_SUM).getSlotScore() + "!");
  }
 
  @Override
  public void writeToLogArea(Message msg){
    logArea.append(msg.getContents().toString());
  }
  @Override
  public void writeToLogArea(String msg){
    logArea.append(msg.toString());
  }
 
  //[START]LISTENERS  (CONTROLLER)
  /**
   * The <code>RollActionListener</code> class is an implementation of the <code>ActionListener</code> which if
   * instantiated and binded to a control, reacts to an incoming event by:<br />
   * a) Checking if its the players turn,<br />
   * b) If the player is the <code>curOwner</code> of the dice, broadcasting a "Roll" command via the comm. module
   */
  class RollActionListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
      if(curGameDice.getCurOwner().equals(client.getClientName())){
        client.getConnection().broadcast(CommandList.ROLLCMD);
      }
    }
  } 
 
  /**
   * The <code>SkipListener</code> class is an implementation of the <code>ActionListener</code> which if
   * instantiated and binded to a control, reacts to an incoming event by:<br />
   * a) Checking if its the players turn,<br />
   * b) If the player is the <code>curOwner</code> of the dice, broadcasting a "Skip" command via the comm. module
   */
  class SkipListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
      if(curGameDice.getCurOwner().equals(client.getClientName())){
        client.getConnection().broadcast(CommandList.SKIPCMD);
        lockAllInputs();
      }
    }
  }
 
  /**
   * The <code>JoinNewListener</code> class is an implementation of the <code>ActionListener</code> which if
   * instantiated and binded to a control, reacts to an incoming event by:<br />
   * a) Prompting the player for confirmation on leaving the current game (via a <code>JOptionPane</code>)<br />
   * b) If the "Yes" option is chosen, reloading the client with a restart
   * (parameter <code>Client.RELOAD_WITH_RESTART</code> used)
   */
  class JoinNewListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent arg0) {
      int decision = JOptionPane.showConfirmDialog(null,
          "Are you sure you want to join a new game (your current process will be lost)?",
          "Join a new game", JOptionPane.YES_NO_OPTION);
      if(decision == JOptionPane.YES_OPTION){
        dispose();
        client.reloadClient(Client.RELOAD_WITH_RESTART);
      }
    }   
  }
 
  /**
   * The <code>ClickDiceListener</code> class is an extension of the <code>MouseAdapter</code>  which if
   * instantiated and binded to a control, reacts to an incoming event by:<br />
   * a) Checking if its the players turn,<br />
   * b) If the player is the <code>curOwner</code> of the dice, broadcasting a "ClickDice" command with attached
   * X- and Y-coordinates specifying the location of the click (This command is neccessary for pruning potentially
   * useful dice from the overall set of dice) via the comm. module
   */
  class ClickDiceListener extends MouseAdapter{
    @Override
    public void mousePressed(MouseEvent e){
      if(curGameDice.getCurOwner().equals(client.getClientName())){
        client.getConnection().broadcast(CommandList.CLICKDICECMD + CommandList.CMD_DELIM + e.getX()  +
            CommandList.CMD_DELIM + e.getY());
      }else{
        writeToLogArea("It is not your turn, " + client.getClientName() + "! Wait for " +
            curGameDice.getCurOwner() + "'s turn to end!\n"); //Write to the log area that its not the players' turn
      }
    }
  }
 
  /**
   * The <code>ClickGamesheetListener</code> class is an extension of the <code>MouseAdapter</code> which if
   * instantiated and binded to a control, reacts to an incoming event by:<br />
   * a) Checking if its the players turn,<br />
   * b) Checking whether the player clicked on a directly-manipulatable score slot on the <code>JTable</code> (
   * for example, the intermediate sum and total sum slots cannot be manipulated directly),<br />
   * c) Checking whether the player clicked on a score slots that has not yet been used (hasn't had a score entered
   * into it),<br />
   * d) If all the previous checks are passed, broadcasting an "Insert" command with an attached player name and row
   * index via the comm. module
   */
  class ClickGamesheetListener extends MouseAdapter{
    @Override
    public void mousePressed(MouseEvent e){
      //Check if this player is the curOwner of the dice
      if(curGameDice.getCurOwner().equals(client.getClientName())){
        int rowIndex = scoreSheet.rowAtPoint(e.getPoint());  
        if(rowIndex == GameSheet.INTERMEDIATE_SUM || rowIndex == GameSheet.TOTAL_SUM ||  //Check, whether 
            rowIndex == GameSheet.UPPERSECTION_BONUS){ //the value is being entered into a proper slot
          writeToLogArea("You cannot enter your score directly into the \"Uppersection bonus\"," +
              " \"Intermediate sum\" or \"Final sum\" cell!\n");
        }else{
          if(client.getGameSheet().getGameSheetContents().get(client.getGameSheet().getClientIndex(client.getClientName()))
              .get(rowIndex).getSlotStatus() == true){
            if(getInsertConfirmation(rowIndex) == JOptionPane.YES_OPTION){
              client.getConnection().broadcast(CommandList.INSERTCMD + CommandList.CMD_DELIM + client.getClientName()
                  + CommandList.CMD_DELIM + rowIndex);
              lockAllInputs();
            }
          }else{
            writeToLogArea("You can not enter your score into the \"" + client.getGameSheet().getGameSheetContents().
                get(0).get(rowIndex).getCombinationName() + "\" slot, because it has already been used!\n");
          }
        }
      }else{
        writeToLogArea("It is not your turn, " + client.getClientName() + "! Wait for " +
            curGameDice.getCurOwner() + "'s turn to end!\n"); //Write to the log area that its not the players' turn
      }
    }
   
    public int getInsertConfirmation(int rowIndex){
      int decision = JOptionPane.showConfirmDialog(null, "Are you sure you'd like to enter " +
        "your score into slot \"" + client.getGameSheet().getGameSheetContents().get(0).
        get(rowIndex).getCombinationName()  + "\"?", "Move confirmation", JOptionPane.YES_NO_OPTION);
      return decision;
    }
  }
 
  /**
   * The <code>SayMessageListener</code> class is an implementation of the <code>ActionListener</code> which if
   * instantiated and binded to a control, reacts to an incoming event by:<br />
   * a) Checking whether the chat's text field contains any text,<br />
   * b) If the chat's text field does contain text, broadcasting a "Said" message with the text fields' contents
   * attached via the comm. module
   */
  class SayMessageListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
      if(sayField.getText().equals(""))return;
      String srcText = sayField.getText()//Get the contained text from the component
      sayField.setText("");
     
      client.getConnection().broadcast(CommandList.SAIDCMD + CommandList.CMD_DELIM + srcText);
    }
  }
  /**
   * Neccessary for keeping the log area scrolled to the bottom.
   */
  class LogScrollListener implements AdjustmentListener{
    @Override
    public void adjustmentValueChanged(AdjustmentEvent arg0) {
      logArea.select(Integer.MAX_VALUE, 0);     
    }
  }
  /**
   * Neccessary for keeping the leaderboard aea scrolled to the top.
   */
  class LeaderboardScrollListener implements AdjustmentListener{
    @Override
    public void adjustmentValueChanged(AdjustmentEvent arg0) {
      leaderArea.select(0, 0);     
    }
  }
  //[END] LISTENERS  (CONTROLLER)
}
TOP

Related Classes of client.frame.GameplayFrame$LeaderboardScrollListener

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.