Package client.frame

Source Code of client.frame.StartupFrame

package client.frame;

import general.statics.function.GUIFunctions;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
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.JTextField;
import javax.swing.JViewport;
import javax.swing.ScrollPaneConstants;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableCellRenderer;

import server.protocol.Message;
import client.Client;
import client.custom.CustomMainPanel;
import client.custom.JCustomField;
import client.custom.JCustomPane;
import client.frame.listener.InstructButtonListener;
import client.frame.listener.LeaveButtonListener;
import client.gui.Constants;
import client.model.QueuedPlayerTableModel;
/**
* The <code>StartupFrame</code> class, a descendant of <code>YahtzeeFrame</code>, is the frame class for displaying the
* startup/login screen of the game. Contains a moderate number of dynamic inputs and controls.
*
* @author Priidu Neemre
*/
public class StartupFrame extends YahtzeeFrame{
 
  private static final long serialVersionUID = 00000001L;
  //Constants for this frame
  public static final int WINDOW_WIDTH = 570;
  public static final int WINDOW_HEIGHT = 230;
  public static final int TEXTFIELD_HEIGHT = 20;
  public static final int TEXTFIELD_WIDTH = 195;
  public static final int JOINED_PANE_HEIGHT = 120;
  public static final int JOINED_PANE_WIDTH = 238;
 
  public static final int GAMERDY_CHECK_INTERVAL = 500;
   
  //MAIN CONTAINER elements of the GUI
  private JPanel bgPanel;
  private JPanel contentPanel;
 
  //HEADING AREA GUI elements
  private JLabel txt_loginHeading;
 
  //JOIN INPUTAREA GUI elements for the start-up frame
  private JLabel txt_joinGame;
 
  private JLabel txt_joinerName;
  private JTextField joinField;
  private JPanel joinerNamePanel;
 
  private JLabel txt_noOfPlayers;
  private JComboBox<Integer> cmbNoOfPlayers;
  private Integer[] possiblePlayers = {1,2,3,4};
  private JPanel noOfPlayersPanel;
 
  private JButton joinBtn;
  private JButton instructionBtn;
  private JPanel posBtnPanel;
 
  private JButton leaveBtn;
  private JPanel negBtnPanel;

  private JPanel joinInputPanel;
 
  //QUEUED PLAYERS' LIST GUI elements
  private QueuedPlayerTableModel queuedModel;
  private JTable queuedTable;
 
  private JLabel txt_queueList;
  private JScrollPane queuedPlayerPane;
  private JPanel queuedPlayerPanel;
 
  private Client client;
  private Timer mainLauncher;
 
  public StartupFrame(Client client){
 
    this.client = client;
       
    buildConfigureJFrame();
    buildConfigureMainContainers();
   
    buildConfigureHeadingArea();
    buildConfigureJoinInputArea();
    buildConfigureJoinerListArea();
    buildConfigureActiveProperties();
   
    this.setVisible(true);
  }
 
  /**
   * Sets the desired properties for the <code>StartupFrame</code> itself.
   */
  private void buildConfigureJFrame(){
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    this.setSize(WINDOW_WIDTH, WINDOW_HEIGHT);
    this.setTitle(GameplayFrame.FRAME_DEFAULT_TITLE + " - Login");
    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(){
    //Create the contentpane JPanel(bgPanel) of the frame, the root container for all following elements
    bgPanel = new CustomMainPanel(Constants.MAIN_BACKGROUND_IMAGE_PATH, Constants.REGULAR_TILE_IMAGE_PATH);
    bgPanel.setLayout(new BoxLayout(bgPanel, BoxLayout.Y_AXIS));
    setContentPane(bgPanel);
   
    contentPanel = new JPanel();
    contentPanel.setLayout(new BoxLayout(contentPanel, BoxLayout.X_AXIS));
    contentPanel.setOpaque(false);
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Heading area" area.
   */
  private void buildConfigureHeadingArea(){
    txt_loginHeading = new JLabel("Yahtzee login");
    txt_loginHeading.setBorder(new EmptyBorder(2,0,2,0));
    txt_loginHeading.setFont(Constants.tahoma_huge_bold);
    txt_loginHeading.setForeground(Color.WHITE);
   
    JPanel headingPanel = new JPanel();
    headingPanel.setLayout(new BoxLayout(headingPanel, BoxLayout.X_AXIS));
    headingPanel.setOpaque(false);
    headingPanel.add(txt_loginHeading);
    bgPanel.add(headingPanel);
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Join input" area.
   */
  private void buildConfigureJoinInputArea(){
   
    txt_joinGame = new JLabel("<html>Please fill the follwing fields to be queued for a game of Yahtzee: </html>");
    txt_joinGame.setAlignmentX(CENTER_ALIGNMENT);
    txt_joinGame.setFont(Constants.tahoma_mediumsmall_bold);
    txt_joinGame.setBorder(new EmptyBorder(2,0,8,0));
    txt_joinGame.setForeground(Color.WHITE);
   
    txt_joinerName = new JLabel("<html>Player name: </html>");
    txt_joinerName.setPreferredSize(new Dimension(80,22));
    txt_joinerName.setMaximumSize(new Dimension(80,22));
    txt_joinerName.setAlignmentX(CENTER_ALIGNMENT);
    txt_joinerName.setFont(Constants.tahoma_mediumsmall_bold);
    txt_joinerName.setForeground(Color.WHITE);
   
    joinField = new JCustomField(Constants.TEXTAREA_TILE_IMAGE_PATH);
    joinField.setPreferredSize(new Dimension(TEXTFIELD_WIDTH, TEXTFIELD_HEIGHT));
    joinField.setMaximumSize(new Dimension(TEXTFIELD_WIDTH, TEXTFIELD_HEIGHT));
    joinField.setFont(Constants.tahoma_mediumsmall_normal);
    joinField.setForeground(Color.WHITE);
    joinField.setCaretColor(Color.WHITE);
    joinField.setOpaque(false);
    joinField.addActionListener(new JoinListener());
       
    joinerNamePanel = new JPanel();
    joinerNamePanel.setLayout(new BoxLayout(joinerNamePanel, BoxLayout.X_AXIS));
    joinerNamePanel.setBorder(new EmptyBorder(1,1,1,1));
    joinerNamePanel.setOpaque(false);
   
    joinerNamePanel.add(txt_joinerName);
    joinerNamePanel.add(joinField);
    joinerNamePanel.add(Box.createHorizontalGlue());

    txt_noOfPlayers = new JLabel("<html>No. of Players:</html>");
    txt_noOfPlayers.setPreferredSize(new Dimension(80,22));
    txt_noOfPlayers.setMaximumSize(new Dimension(80,22));
    txt_noOfPlayers.setFont(Constants.tahoma_mediumsmall_bold);
    txt_noOfPlayers.setForeground(Color.WHITE);
   
    cmbNoOfPlayers = new JComboBox<Integer>(possiblePlayers);
    cmbNoOfPlayers.setPreferredSize(new Dimension(40,22));
    cmbNoOfPlayers.setMaximumSize(new Dimension(40,22));
    cmbNoOfPlayers.addActionListener(new PlayerNumberListener());
    cmbNoOfPlayers.setOpaque(false);
   
    noOfPlayersPanel = new JPanel();
    noOfPlayersPanel.setLayout(new BoxLayout(noOfPlayersPanel, BoxLayout.X_AXIS));
    noOfPlayersPanel.setBorder(new EmptyBorder(1,1,4,1));
    noOfPlayersPanel.setOpaque(false);
   
    noOfPlayersPanel.add(txt_noOfPlayers);
    noOfPlayersPanel.add(cmbNoOfPlayers);
    noOfPlayersPanel.add(Box.createHorizontalGlue());

    joinBtn = new JButton("Join");
    joinBtn.setPreferredSize(new Dimension(70, 22));
    joinBtn.addActionListener(new JoinListener());
   
    instructionBtn = new JButton("Instructions");
    instructionBtn.setPreferredSize(new Dimension(100, 22));
    instructionBtn.addActionListener(new InstructButtonListener());
     
    posBtnPanel = new JPanel();
    posBtnPanel.setLayout(new BoxLayout(posBtnPanel, BoxLayout.X_AXIS));
    posBtnPanel.setBorder(new EmptyBorder(1,1,2,1));
    posBtnPanel.setOpaque(false);

    posBtnPanel.add(joinBtn);
    posBtnPanel.add(Box.createRigidArea(new Dimension(4, joinBtn.getHeight())));
    posBtnPanel.add(instructionBtn);
    posBtnPanel.add(Box.createHorizontalGlue());
     
    joinInputPanel = new JPanel();
    joinInputPanel.setLayout(new BoxLayout(joinInputPanel, BoxLayout.Y_AXIS));
    joinInputPanel.setBorder(new EmptyBorder(0,3,0,1));
    joinInputPanel.setOpaque(false);
   
    joinInputPanel.add(txt_joinGame)
    joinInputPanel.add(joinerNamePanel)
    joinInputPanel.add(noOfPlayersPanel);
    joinInputPanel.add(Box.createVerticalGlue());
    joinInputPanel.add(posBtnPanel);

    contentPanel.add(joinInputPanel)
  }
 
  /**
   * Instantiates variables and enforces properties for all the elements of the GUI's "Joiner list" area.
   */
  private void buildConfigureJoinerListArea(){
   
    txt_queueList = new JLabel(String.format("<html>Clients queued for a %d-player game <font color=red>" +
        "(Enables after \"Join\")</font>: </html>", cmbNoOfPlayers.getSelectedItem()));
    txt_queueList.setPreferredSize(new Dimension(150, 30));
    txt_queueList.setFont(Constants.tahoma_mediumsmall_bold);
    txt_queueList.setAlignmentX(CENTER_ALIGNMENT);
    txt_queueList.setForeground(Color.WHITE);
    txt_queueList.setBorder(new EmptyBorder(5,0,8,0));
   
    queuedModel = new QueuedPlayerTableModel(client.getJoinedList());
   
    queuedTable = new JTable(queuedModel);
    queuedTable.getTableHeader().setReorderingAllowed(false);
    queuedTable.getTableHeader().setResizingAllowed(false);
    GUIFunctions.alignJTableContents(JLabel.LEFT, queuedTable);
    queuedTable.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    GUIFunctions.setJTableColumnWidth(queuedTable, 18, QueuedPlayerTableModel.QUEUED_TABLE_INDEX_COLUMN);
    GUIFunctions.setJTableColumnWidth(queuedTable, 90, QueuedPlayerTableModel.QUEUED_TABLE_NAME_COLUMN);
    GUIFunctions.setJTableColumnWidth(queuedTable, 125, QueuedPlayerTableModel.QUEUED_TABLE_DATE_COLUMN);

    DefaultTableCellRenderer cellRend = (DefaultTableCellRenderer) queuedTable.getCellRenderer(0, 0);
    cellRend.setForeground(Color.WHITE);
    cellRend.setOpaque(false);
   
    queuedTable.setOpaque(false);
    queuedTable.getTableHeader().setOpaque(false);
    queuedTable.getTableHeader().setBackground(new Color(0,true));
    queuedTable.getTableHeader().setPreferredSize(new Dimension(0,18));   
   
    queuedPlayerPane = new JCustomPane(queuedTable, Constants.TEXTAREA_TILE_IMAGE_PATH);
    queuedPlayerPane.setPreferredSize(new Dimension(JOINED_PANE_WIDTH, JOINED_PANE_HEIGHT));
    queuedPlayerPane.setMaximumSize(new Dimension(JOINED_PANE_WIDTH, JOINED_PANE_HEIGHT));
    queuedPlayerPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER);
    queuedPlayerPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    queuedPlayerPane.getViewport().setOpaque(false);
    queuedPlayerPane.setOpaque(false);
    queuedPlayerPane.setColumnHeader(new JViewport());
    queuedPlayerPane.getColumnHeader().setOpaque(false);
   
    queuedPlayerPanel = new JPanel();
    queuedPlayerPanel.setLayout(new BoxLayout(queuedPlayerPanel, BoxLayout.Y_AXIS));
    queuedPlayerPanel.setBorder(new EmptyBorder(3,3,2,2));
    queuedPlayerPanel.setOpaque(false);
   
    leaveBtn = new JButton("Leave");
    leaveBtn.setPreferredSize(new Dimension(70, 22));
    leaveBtn.addActionListener(new LeaveButtonListener(client));
   
    negBtnPanel = new JPanel();
    negBtnPanel.setLayout(new BoxLayout(negBtnPanel, BoxLayout.X_AXIS));
    negBtnPanel.setBorder(new EmptyBorder(3,1,0,1));
    negBtnPanel.setOpaque(false);
   
    negBtnPanel.add(Box.createHorizontalGlue())
    negBtnPanel.add(leaveBtn);
   
    queuedPlayerPanel.add(txt_queueList);
    queuedPlayerPanel.add(queuedPlayerPane);
    queuedPlayerPanel.add(negBtnPanel);
   
    contentPanel.add(queuedPlayerPanel);
    getContentPane().add(contentPanel);
  }
 
  /**
   * Instantiates variables and enforces properties for all the GUI's dynamic components.
   */
  private void buildConfigureActiveProperties(){
    //Instantiate the mainLauncher timer in the constructor to avoid NPEs and other bugs
    mainLauncher = new Timer(GAMERDY_CHECK_INTERVAL, new LauncherTickListener());
  }
 
  @Override
  public void updateGUIIndicators() {
    switch(client.getState()){
    case PROCESS_LAUNCHED:
      setTitle(FRAME_DEFAULT_TITLE);
      joinBtn.setEnabled(true);
      joinField.setEnabled(true);
      cmbNoOfPlayers.setEnabled(true);
      break;
    case INITIATING_CONNECTION:
      setTitle("Initiating a connection with the gameserver...");
      lockAllInputs();
      queuedModel.updateQueuedPlayerList();
      break;
    default:
      break;
    }
    repaint();
 

  /**
   * Locks all the player-manipulatable inputs of the frame.
   */
  private void lockAllInputs(){
    joinBtn.setEnabled(false);
    joinField.setEnabled(false);
    cmbNoOfPlayers.setEnabled(false);
  }
 
  /**
   * Notifies the player about the chosen name already being in use on the server and transitions the client back into the
   * <code>PROCESS_LAUNCHED</code> state, also stoping the mainframe launcher timer.
   */
  public void notifyNameInUse(){
    JOptionPane.showMessageDialog(null, "The server has detected that the name you picked is already in use!\n" +
        "Please pick another player name!");
    client.bInitiatingConnectionTOProcessLaunched();
    mainLauncher.stop();
    updateGUIForeign();
  }
 
  @Override
  public void writeToLogArea(String message) {}
  @Override
  public void writeToLogArea(Message msg) {}
 
  //[START]GETTERS AND SETTERS
  public StartupFrame getThis(){
    return this;
  }
  //[END]GETTERS AND SETTERS

  //[START]LISTENERS (CONTROLLER)
  /**
   * The <code>JoinListener</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) Making sure that the name entered to the "player name" field was of appropriate length. <br />
   * b) If so, transitioning the client to the <code>INSTANTIATING_CONNECTION</code> state. <br />
   */
  class JoinListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
      String tempName = joinField.getText().trim();
      if(tempName.length() < Client.CLIENT_NAME_MINLENGTH || (tempName.length() > Client.CLIENT_NAME_MAXLENGTH)){
        JOptionPane.showMessageDialog(getThis(), "Invalid player name! Must have a length of "
            + Client.CLIENT_NAME_MINLENGTH  + " to " + Client.CLIENT_NAME_MAXLENGTH + " characters!");
      }else{
        lockAllInputs();
        client.fPrcoessLaunchedTOInitiatingConnection(tempName, (Integer)cmbNoOfPlayers.getSelectedItem());
        mainLauncher.start();
      }
    }
  }
 
  /**
   * The <code>LaunchTickListener</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) Calling a repaint on all GUI indicators,<br />
   * b) Checking whether all the vital components for game-start have been received from the gameserver,<br />
   * c) If all the vital components have been received, transition the client to the <code>GAME_IN_PROGRESS</code> state and
   * close the startup frame.
   */
  class LauncherTickListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
      //Update the GUI every time the constraints for game start are checked
      updateGUIIndicators();
      //Check whether the client has successfully received all the initial data for a game-start
      if((client.getClientName() == null) || (client.getDice() == null) || (client.getGameSheet() == null) ||
          (client.getLeaderboard() == null) || (client.getNoOfPlayers() > Client.MAX_NO_OF_PLAYERS ||
              client.getNoOfPlayers() < Client.MIN_NO_OF_PLAYERS)){
        return;
      }else{
        //The client has received all the initial data from the gameserver
        mainLauncher.stop();
        client.fInitiatingConnectionTOGameInProgress();
        getThis().dispose();
      }
    }   
  }
  /**
   * The <code>PlayerNumberListener</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) Updating the text above the joiner area accordingly to the number of players chosen.
   */
  class PlayerNumberListener implements ActionListener{
    @Override
    public void actionPerformed(ActionEvent e) {
      txt_queueList.setText(String.format("<html>Clients queued for a %d-player game <font color=red>" +
          "(Enables after \"Join\")</font>: </html>", cmbNoOfPlayers.getSelectedItem()));
   
  }
}
TOP

Related Classes of client.frame.StartupFrame

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.