Coverage Summary for Class: PlayerGUI (it.polimi.ingsw.view.GUI)
Class |
Method, %
|
Line, %
|
PlayerGUI |
0%
(0/49)
|
0%
(0/1112)
|
PlayerGUI$1 |
0%
(0/2)
|
0%
(0/11)
|
PlayerGUI$2 |
0%
(0/2)
|
0%
(0/3)
|
PlayerGUI$3 |
0%
(0/1)
|
0%
(0/1)
|
Total |
0%
(0/54)
|
0%
(0/1127)
|
package it.polimi.ingsw.view.GUI;
import it.polimi.ingsw.view.*;
import it.polimi.ingsw.controller.*;
import it.polimi.ingsw.model.*;
import javax.sound.sampled.*;
import javax.swing.*;
import java.awt.*;
import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.net.Socket;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Random;
import static java.awt.Color.*;
import static java.awt.GridBagConstraints.*;
import static javax.swing.JOptionPane.*;
/**
* class which represent the player on the client side, mutable,
* implements Serializable because it will be sent in the socket network
* @author Ettori Faccincani
*/
public class PlayerGUI extends Player implements Serializable, PlayerI {
private final transient int DIM = 9;
private final transient int ROWS = 6;
private final transient int COLS = 5;
private final transient int cardBorderSize = 2;
private final transient java.awt.Color borderColor = BLACK;
private final transient int libFullX = 6;
private final transient int libFullY = 7;
private final transient Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
private final transient GridBagConstraints gbc = new GridBagConstraints();
private final transient GridBagConstraints gbc2 = new GridBagConstraints();
private transient JFrame mainFrame;
private transient JPanel infoBox, internalPanelSide, internalPanelHigh, internalPanelLow, player1Panel, player2Panel, player3Panel, gameBoardPanel, myLibraryPanel, chatPanel, CO1Panel, CO2Panel, POPanel, chairmanPanel, mainPanel, chooseColPanel;
private transient JLabel POLabel, CO1Label, CO2Label, pointsCO1Label, pointsCO2Label, chairmanLabel, library1Label, library2Label, library3Label, boardLabel, libraryLabel, generalLabel;
private transient JTextField chairmanInfo, activeTurnInfo, curPointsInfo, titleInfo, insertMessage, insertPlayer, CO1Title, CO2Title, POTitle, chairmanTitle, eventText, textInput;
private transient JTextArea library1Text, library2Text, library3Text, boardText, myLibraryText, chatTitle, tempChatHistory;
private transient JRadioButton r1, r2, r3, r4, r5;
private transient ButtonGroup btnGroup;
private transient JScrollPane chatHistory;
private transient JButton pickCardsBtn, sendMessageBtn, sendBtn;
private final transient JLabel[][] boardCards = new JLabel[DIM][DIM];
private final transient JLabel[][] myLibraryCards = new JLabel[ROWS][COLS];
private final transient ArrayList<JLabel[][]> otherLibrariesCards = new ArrayList<>(Arrays.asList(new JLabel[ROWS][COLS], new JLabel[ROWS][COLS], new JLabel[ROWS][COLS]));
private transient ArrayList<Integer> cardsPicked = new ArrayList<>();
private transient GameI server;
private final transient ClassLoader classLoader = getClass().getClassLoader();
/**
* constructor that copies a generic Player object inside a new PlayerTUI object
* @param p the Player object to copy, received by the server
*/
public PlayerGUI(Player p) throws RemoteException {
super();
name = p.getName();
isChairMan = p.getIsChairMan();
library = new Library(p.library);
objective = p.getPrivateObjective();
pointsUntilNow = p.pointsUntilNow;
board = new Board(p.board);
librariesOfOtherPlayers = new ArrayList<>(p.librariesOfOtherPlayers);
CO_1_Done = p.getCO_1_Done();
CO_2_Done = p.getCO_2_Done();
fullChat = p.getFullChat();
chairmanName = p.chairmanName;
activeName = p.activeName;
numPlayers = p.numPlayers;
endGame = p.getEndGame();
pointsMap = p.pointsMap;
}
/**
* standard constructor, starts the main game process on the client side
* @param mode type of the network chosen by the user
* @author Ettori
*/
public PlayerGUI(NetMode mode, String opt) throws RemoteException {
super();
screenSize.height = 950;
screenSize.width = 1600;
System.setProperty("java.rmi.server.hostname", IP.activeIP);
uiMode = UIMode.GUI;
netMode = mode;
System.out.println("\nSoon you will need to enter your nickname for the game");
try {
mySocket = new Socket(IP.activeIP, Initializer.PORT);
outStream = new ObjectOutputStream(mySocket.getOutputStream());
inStream = new ObjectInputStream(mySocket.getInputStream());
outStream.flush();
if(!opt.equals("yes")){
outStream.writeObject(false);
}
}catch (Exception e){alert("\nServer is inactive, try later"); connectionLost(e);}
System.out.println("\nClient connected");
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/song.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.loop(Clip.LOOP_CONTINUOUSLY);
FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);
gainControl.setValue(-10.0f); //lower the volume of 10 decibel
clip.start();
}catch(Exception e){
e.printStackTrace();
}
new Thread(this::showChooseNameWindow).start();
}
/**
* Clone the player on the client in the player on the server
* @author Ettori
* @param p the Player that will be cloned in the current Object
*/
public void clone(PlayerGUI p){
name = p.name;
isChairMan = p.isChairMan;
library = new Library(p.library);
objective = p.objective;
pointsUntilNow = p.pointsUntilNow;
board = new Board(p.board);
librariesOfOtherPlayers = new ArrayList<>(p.librariesOfOtherPlayers);
CO_1_Done = p.CO_1_Done;
CO_2_Done = p.CO_2_Done;
fullChat = p.fullChat;
chairmanName = p.chairmanName;
activeName = p.activeName;
numPlayers = p.numPlayers;
endGame = p.endGame;
pointsMap = p.pointsMap;
}
/**
* method that update the information about the game
* @author Ettori
*/
private void updateInfo(){
//Game.waitForSeconds(Game.fastTimer);
SwingUtilities.invokeLater(() -> {
//funcional programming for set the correct PO and CO
pointsCO1Label.setIcon(board.pointsCO_1.size() == 0 ? new ImageIcon (new ImageIcon(classLoader.getResource("scoring tokens/scoring_back_EMPTY.jpg")).getImage().getScaledInstance(Dimensions.pointsDim, Dimensions.pointsDim, Image.SCALE_SMOOTH)) : new ImageIcon (new ImageIcon(classLoader.getResource(Dimensions.pathPointsCO + "_" + board.pointsCO_1.peekLast() + ".jpg")).getImage().getScaledInstance(Dimensions.pointsDim, Dimensions.pointsDim, Image.SCALE_SMOOTH)));
pointsCO2Label.setIcon(board.pointsCO_2.size() == 0 ? new ImageIcon (new ImageIcon(classLoader.getResource("scoring tokens/scoring_back_EMPTY.jpg")).getImage().getScaledInstance(Dimensions.pointsDim, Dimensions.pointsDim, Image.SCALE_SMOOTH)) : new ImageIcon (new ImageIcon(classLoader.getResource(Dimensions.pathPointsCO + "_" + board.pointsCO_2.peekLast() + ".jpg")).getImage().getScaledInstance(Dimensions.pointsDim, Dimensions.pointsDim, Image.SCALE_SMOOTH)));
activeTurnInfo.setText(" The active player is " + activeName + " ");
curPointsInfo.setText(" " + pointsUntilNow + " points achieved until now ");
tempChatHistory.setText(fullChat);
mainFrame.revalidate();
mainFrame.repaint();
});
}
/**
* method that update the board of the game
* @author Ettori
*/
private void updateBoard(){
SwingUtilities.invokeLater(() ->{
String path;
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++){
if(i == libFullX && j == libFullY)
continue;
path = board.getGameBoard()[i][j].imagePath.trim();
try {
boardCards[i][j].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource(path)).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
}catch(Exception ignored){}
boardCards[i][j].setVisible(board.getGameBoard()[i][j].color != it.polimi.ingsw.model.Color.EMPTY);
}
}
//show or not show the card of the end game (if not show the game is ending)
boardCards[libFullX][libFullY].setVisible(!endGame);
mainFrame.revalidate();
mainFrame.repaint();
});
}
/**
* method that update the library of the active player
* @author Ettori
*/
private void updateMyLibrary(){
SwingUtilities.invokeLater(() ->{
for(int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
try {
myLibraryCards[i][j].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource(library.gameLibrary[i][j].imagePath)).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
}
catch (Exception ignored){}
myLibraryCards[i][j].setVisible(library.gameLibrary[i][j].color != it.polimi.ingsw.model.Color.EMPTY);
}
}
mainFrame.revalidate();
mainFrame.repaint();
//myLibraryCards[2][2].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource("item tiles/Cornici1.3.png")).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
});
//myLibraryCards[2][2].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource("item tiles/Cornici1.3.png")).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
}
/**
* method that update the event text of the game, notifying the most recent event
* @author Ettori
*/
private void updateEventText(String s){
SwingUtilities.invokeLater(() ->{
try {
eventText.setText(s);
}catch (Exception ignored){}
mainFrame.revalidate();
mainFrame.repaint();
});
}
/**
* method that update the libraries of all the player except the one which is active
* @author Ettori
*/
private void updateOtherLibraries(){
SwingUtilities.invokeLater(() ->{
library1Text.setText(" Library of " + librariesOfOtherPlayers.get(0).name + " (" + pointsMap.get(librariesOfOtherPlayers.get(0).name) + " points) ");
//plot the frist library of other
for(int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
try {
otherLibrariesCards.get(0)[i][j].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource(librariesOfOtherPlayers.get(0).gameLibrary[i][j].imagePath)).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
}catch(Exception ignored){}
otherLibrariesCards.get(0)[i][j].setVisible(librariesOfOtherPlayers.get(0).gameLibrary[i][j].color != it.polimi.ingsw.model.Color.EMPTY);
}
}
//plot the second library of other
if(numPlayers >= 3){
library2Text.setText(" Library of " + librariesOfOtherPlayers.get(1).name + " (" + pointsMap.get(librariesOfOtherPlayers.get(1).name) + " points) ");
for(int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
try {
otherLibrariesCards.get(1)[i][j].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource(librariesOfOtherPlayers.get(1).gameLibrary[i][j].imagePath)).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
}catch(Exception ignored){}
otherLibrariesCards.get(1)[i][j].setVisible(librariesOfOtherPlayers.get(1).gameLibrary[i][j].color != it.polimi.ingsw.model.Color.EMPTY);
}
}
}
//plot the third library of other
if(numPlayers >= 4){
library3Text.setText(" Library of " + librariesOfOtherPlayers.get(2).name + " (" + pointsMap.get(librariesOfOtherPlayers.get(2).name) + " points) ");
for(int i = 0; i < ROWS; i++) {
for (int j = 0; j < COLS; j++) {
try {
otherLibrariesCards.get(2)[i][j].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource(librariesOfOtherPlayers.get(2).gameLibrary[i][j].imagePath)).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
}catch (Exception ignored){}
otherLibrariesCards.get(2)[i][j].setVisible(librariesOfOtherPlayers.get(2).gameLibrary[i][j].color != it.polimi.ingsw.model.Color.EMPTY);
}
}
}
mainFrame.revalidate();
mainFrame.repaint();
});
}
/**
* Function that update the GUI with the new information
* @author Ettori Giammusso
*/
private void updateGUI(){
updateInfo();
updateBoard();
updateMyLibrary();
updateOtherLibraries();
}
/**
* check if the card was already picked before
* @author Ettori
* @param x the x coord
* @param y the y coord
* @return -1 if it was not picked before, the current index if it was picked before
*/
private int getCardIndex(int x, int y){
for(int i = 0; i < cardsPicked.size(); i += 2){
if(cardsPicked.get(i) == x && cardsPicked.get(i + 1) == y)
return i;
}
return -1;
}
/**
* method that reads the cards chosen and the column chosen, then it tries to pick the cards (if possible)
* @author Ettori
*/
private void tryToPickCards(){
ArrayList<Integer> cards = new ArrayList<>(cardsPicked);
cardsPicked = new ArrayList<>();
int col = -1;
if(r1.isSelected())
col = 1;
if(r2.isSelected())
col = 2;
if(r3.isSelected())
col = 3;
if(r4.isSelected())
col = 4;
if(r5.isSelected())
col = 5;
col--;
if(cards.size() == 0 || !board.areCardsPickable(cards) || !library.checkCol(col, cards.size() / 2))
alert("Invalid Selection");
else{
activeName = "...";
pickCards(cards, col);
updateGUI();
boolean change_1 = checkCO();
boolean change_2 = checkLibFull();
if(change_1 || change_2)
updateInfo();
sendDoneMove(); // send the move to the server
}
//color the border of the cards selected
for(int i = 0; i < cards.size(); i += 2)
boardCards[cards.get(i)][cards.get(i + 1)].setBorder(BorderFactory.createLineBorder(borderColor, 0));
}
/**
* method for choosing the nickname of the player for the future game, implemented with the Swing GUI
* @author Ettori Giammusso
*/
private void showChooseNameWindow(){
mainFrame = new JFrame("My Shelfie");
mainPanel = new JPanel(new GridBagLayout());
//tempPanels are used to replace the textArea and the Button after a person has chosen the name in order to prevent the "My Shelfie" label to move
JPanel tempPanel1 = new JPanel();
tempPanel1.setPreferredSize(new Dimension(Dimensions.placeholderW, Dimensions.placeholderH));
tempPanel1.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel1.setOpaque(false);
JPanel tempPanel2 = new JPanel();
tempPanel2.setPreferredSize(new Dimension(Dimensions.placeholderW, Dimensions.placeholderH));
tempPanel2.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel2.setOpaque(false);
//WALLPAPER:
//if you want a random wallpaper, uncomment the following line and comment the next line
JLabel generalLabelChooseName = new JLabel(new ImageIcon(new ImageIcon("Publisher material/Display_" + (new Random().nextInt(5) + 1) + ".jpg").getImage().getScaledInstance(screenSize.width * 5 / 6, screenSize.height * 9 / 10, Image.SCALE_SMOOTH)));
//JLabel generalLabelChooseName = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("Publisher material/Display_1.jpg")).getImage().getScaledInstance(screenSize.width * 5 / 6, screenSize.height * 9 / 10, Image.SCALE_SMOOTH)));
generalLabelChooseName.setPreferredSize(new Dimension(screenSize.width * 5 / 6, screenSize.height * 8 / 10 + 65));
generalLabelChooseName.setLayout(new GridBagLayout());
//my shelfie title
JLabel myShelfieTitleLabel = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("Publisher material/Title 2000x618px.png")).getImage().getScaledInstance(screenSize.width * 4 / 6, screenSize.height * 4 / 10, Image.SCALE_SMOOTH)));
sendBtn = new JButton("Choose Name"); // button to send the name
textInput = new JTextField(20); // textbox input from the user
textInput.setBounds(100, 20, 165, 25);
textInput.addActionListener(event -> sendBtn.doClick()); // if you press enter on the keyboard, automatically use sendBtn
sendBtn.addActionListener((event) ->{ // function of event listener
NameStatus status = null;
name = textInput.getText();
if(name.length() == 0 || name.charAt(0) == '@' || name.equals("all") || name.equals("names") || name.equals("...") || name.equals("exit")){
alert("Name invalid, choose another name");
textInput.setText("");
return;
}
try {
outStream.writeObject(name);
status = (NameStatus) inStream.readObject();
}catch(Exception e){connectionLost(e);}
if(status == NameStatus.NOT_TAKEN){
alert("\nName: '" + name + "' accepted by the server!");
textInput.setVisible(false);
sendBtn.setVisible(false);
gbc2.gridx = 0;
gbc2.gridy = 3;
generalLabelChooseName.add(tempPanel1,gbc2);
gbc2.gridx = 0;
gbc2.gridy = 4;
generalLabelChooseName.add(tempPanel1,gbc2);
new Thread(this::getInitialState).start();
return;
}
//start the persistance
if(status == NameStatus.OLD){
alert("\nName: " + name + " was found in a previous game");
textInput.setVisible(false);
sendBtn.setVisible(false);
gbc2.gridx = 0;
gbc2.gridy = 3;
generalLabelChooseName.add(tempPanel1,gbc2);
gbc2.gridx = 0;
gbc2.gridy = 4;
generalLabelChooseName.add(tempPanel1,gbc2);
new Thread(this::getInitialState).start();
return;
}
if(status == NameStatus.NOT_FOUND){
alert("\nAnother game is running and your name was not found...");
System.exit(0);
}
if(status == NameStatus.FOUND){
textInput.setVisible(false);
sendBtn.setVisible(false);
gbc2.gridx = 0;
gbc2.gridy = 3;
generalLabelChooseName.add(tempPanel1,gbc2);
gbc2.gridx = 0;
gbc2.gridy = 4;
generalLabelChooseName.add(tempPanel1,gbc2);
new Thread(this::getPreviousState).start();
return;
}
alert("Name Taken, choose another name");
textInput.setText("");
});
gbc2.gridx=0;
gbc2.gridy=0;
generalLabelChooseName.add(myShelfieTitleLabel,gbc2);
gbc2.gridx=0;
gbc2.gridy=1;
gbc2.insets = new Insets(0,0,15,0);
generalLabelChooseName.add(textInput,gbc2);
gbc2.gridx=0;
gbc2.gridy=2;
gbc2.insets = new Insets(0,0,0,0);
generalLabelChooseName.add(sendBtn,gbc2);
gbc2.gridx=0;
gbc2.gridy=0;
mainPanel.add(generalLabelChooseName,gbc2);
mainFrame.add(new JScrollPane(mainPanel), BorderLayout.CENTER);
mainFrame.setSize((int) (Toolkit.getDefaultToolkit().getScreenSize().width * 0.9), (int) (Toolkit.getDefaultToolkit().getScreenSize().height * 0.9));
mainFrame.setResizable(false);
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setTitle("My Shelfie");
mainFrame.setIconImage(new ImageIcon(classLoader.getResource("Publisher material/Icon 50x50px.png")).getImage());
//mainFrame.pack(); // setup of the window
mainFrame.setLocationRelativeTo(null); //the frame is centered when printed on the screen
mainFrame.setVisible(true); // show the frame
}
/**
* Receive the status of the player (previously disconnected) from the server and restart the game
* @author Ettori Faccincani
*/
private void getPreviousState(){
PlayerGUI p;
try {
alert("Reconnecting to the running game...");
p = new PlayerGUI((Player)inStream.readObject());
clone(p);
Thread th = new Thread(this::initGUI);
th.start();
th.join();
updateInfo();
if(netMode == NetMode.RMI)
new Thread(this::listenForEndGame).start();
}catch(Exception e){connectionLost(e);}
try {
server = (GameI)LocateRegistry.getRegistry(IP.activeIP, Initializer.PORT_RMI).lookup("Server");
} catch (RemoteException | NotBoundException e) {
connectionLost(e);
}
if(netMode == NetMode.RMI) {
try {
server.addClient(name, this);
} catch (RemoteException e) {
connectionLost(e);
}
}
try {
outStream.writeObject(true);
} catch (IOException e) {
connectionLost(e);
}
updateInfo();
if(netMode == NetMode.SOCKET) {
new Thread(this::waitForEvents).start();
new Thread(this::ping).start();
}
else
new Thread(this::pingRMI).start();
}
/**
* Receive the status of the player from the server and attend the start of the game
* @author Ettori Faccincani
*/
private void getInitialState(){
PlayerGUI p;
try {
p = new PlayerGUI((Player)inStream.readObject());
clone(p);
activeName = chairmanName;
Thread th = new Thread(this::initGUI);
th.start();
th.join();
updateInfo();
if(netMode == NetMode.RMI)
new Thread(this::listenForEndGame).start();
}catch(Exception e){connectionLost(e);}
try {
server = (GameI) LocateRegistry.getRegistry(IP.activeIP, Initializer.PORT_RMI).lookup("Server");
} catch (RemoteException | NotBoundException e) {
connectionLost(e);
}
if(netMode == NetMode.RMI) {
try {
server.addClient(name, this);
} catch (RemoteException e) {
connectionLost(e);
}
}
try {
outStream.writeObject(true);
} catch (IOException e) {
connectionLost(e);
}
if(netMode == NetMode.SOCKET) {
new Thread(this::waitForEvents).start();
new Thread(this::ping).start();
}
else
new Thread(this::pingRMI).start();
}
/**
* function used to wait for notification from the server while the player is NON-active
* @author Ettori Faccincani
*/
private void waitForEvents(){
while(true){
try {
Message msg = (Message) inStream.readObject();
switch (msg.getType()) {
case YOUR_TURN -> handleYourTurnEvent();
case CHANGE_TURN -> handleChangeTurnEvent(msg);
case UPDATE_UNPLAYABLE -> handleUpdateUnplayableEvent(msg);
case UPDATE_GAME -> handleUpdateGameEvent(msg);
case FINAL_SCORE -> handleFinalScoreEvent(msg);
case CHAT -> handleChatEvent(msg);
case CO_1 -> handleCO_1Event(msg);
case CO_2 -> handleCO_2Event(msg);
case LIB_FULL -> handleLibFullEvent(msg);
case DISCONNECTED -> handleDisconnectedEvent(msg);
case LOST_CLIENT -> handleLostClientEvent(msg);
case SHOW_EVENT -> handleShowEvent(msg);
}
}catch(Exception e){
connectionLost(e);
}
}
}
/**
* helper function for handling the show event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleShowEvent(Message msg){
if(msg.getAuthor() != null && msg.getAuthor().equals("win")){
updateEventText(" The game is finished, look at the results");
alert((String) msg.getContent());
Game.waitForSeconds(Game.waitTimer);
System.exit(0);
}
updateEventText(" " + msg.getContent());
}
/**
* helper function for handling the client (not active) disconnection notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleLostClientEvent(Message msg){
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/disconnect.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
}catch(Exception e){
e.printStackTrace();
}
updateEventText(" Player " + msg.getAuthor() + " disconnected from the game");
}
/**
* helper function for handling the turn event notification from the server
* @author Ettori
*/
private void handleYourTurnEvent(){
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/turn.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
}catch(Exception e){
e.printStackTrace();
}
activeName = name;
if(board.isBoardUnplayable())
fixUnplayableBoard();
if(!endGame) {
updateBoard();
updateOtherLibraries();
}
updateInfo();
updateEventText(" Your turn is now started, play your move !");
turnThread = new Thread(() ->{
try {
Thread.sleep(1000 * 60 * 5);
} catch (InterruptedException e) {
return;
}
if(activeName.equals(name))
sendDoneMove();
});
turnThread.start();
}
/**
* helper function for handling the change event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleChangeTurnEvent(Message msg){
activeName = (String) msg.getContent();
updateInfo();
updateBoard();
updateOtherLibraries();
updateEventText(" Now " + activeName + " is playing his turn...");
}
/**
* helper function for handling the unplayble board fixing event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleUpdateUnplayableEvent(Message msg){
board = (Board) msg.getContent();
updateBoard();
updateEventText(" Board updated because it was unplayable");
}
/**
* helper function for handling the update game notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleUpdateGameEvent(Message msg){
if(netMode == NetMode.SOCKET)
sendToServer(new Message(MessageType.STOP, null, null));
PlayerSend p = (PlayerSend) msg.getContent();
board = p.board;
for(int i = 0; i < numPlayers - 1; i++){
if(librariesOfOtherPlayers.get(i).name.equals(msg.getAuthor()))
librariesOfOtherPlayers.set(i, p.library);
}
pointsMap.put(msg.getAuthor(), p.pointsUntilNow);
if(endGame)
updateGUI();
updateEventText(" Player " + msg.getAuthor() + " made his move, now wait for the turn to change...");
}
/**
* helper function for handling the final score calculation event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleFinalScoreEvent(Message msg){
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/ending.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
}catch(Exception e){
e.printStackTrace();
}
updateEventText(" The game is finished, look at the results");
alert("\nThe game is finished, this is the final scoreboard:\n\n" + msg.getContent());
Game.waitForSeconds(Game.showTimer);
System.exit(0);
}
/**
* helper function for handling the chat message event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleChatEvent(Message msg){
fullChat += msg.getContent();
updateInfo();
}
/**
* helper function for handling the achievement of the first common objective event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleCO_1Event(Message msg){
updateEventText(" " + msg.getAuthor() + " completed the first common objective getting " + msg.getContent() + " points");
board.pointsCO_1.remove(board.pointsCO_1.size() - 1);
updateInfo();
}
/**
* helper function for handling the achievement of the second common objective event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleCO_2Event(Message msg){
updateEventText(" " + msg.getAuthor() + " completed the second common objective getting " + msg.getContent() + " points");
board.pointsCO_2.remove(board.pointsCO_2.size() - 1);
updateInfo();
}
/**
* helper function for handling the completion of the library event notification from the server
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleLibFullEvent(Message msg){
updateEventText(" " + msg.getAuthor() + " completed the library, the game will continue until the next turn of " + chairmanName);
endGame = true;
boardCards[libFullX][libFullY].setVisible(false);
}
/**
* helper function for handling the disconnection event notification from the server (of the active client)
* @author Ettori
* @param msg the message containing the necessary information for reacting to the event
*/
private void handleDisconnectedEvent(Message msg){
updateEventText(" The active player (" + msg.getAuthor() + ") disconnected from the game");
if(netMode == NetMode.SOCKET)
sendToServer(new Message(MessageType.STOP, null, null));
}
/**
* method that checks if the current player completed a common objective, and in that case notify all the other players (and add the points)
* @author Ettori
* @return true iff one of the objectives was completed
*/
private boolean checkCO(){
int points, lastIndex;
boolean change = false;
try {
if (board.commonObjective_1.algorithm.checkMatch(library.gameLibrary) && !CO_1_Done && board.pointsCO_1.size() > 0) { // you can't take the CO if you already did
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/CO1.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
}catch(Exception e){
e.printStackTrace();
}
lastIndex = board.pointsCO_1.size() - 1;
points = board.pointsCO_1.get(lastIndex);
board.pointsCO_1.remove(lastIndex);
pointsUntilNow += points;
CO_1_Done = true;
sendToServer(new Message(MessageType.CO_1, name, Integer.toString(points)));
updateEventText(" Well done, you completed the first common objective and you gain " + points + " points...");
Game.waitForSeconds(Game.showTimer);
change = true;
}
if (board.commonObjective_2.algorithm.checkMatch(library.gameLibrary) && !CO_2_Done && board.pointsCO_2.size() > 0) {
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/CO2.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
}catch(Exception e){
e.printStackTrace();
}
lastIndex = board.pointsCO_2.size() - 1;
points = board.pointsCO_2.get(lastIndex);
board.pointsCO_2.remove(lastIndex);
pointsUntilNow += points;
CO_2_Done = true;
sendToServer(new Message(MessageType.CO_2, name, Integer.toString(points)));
updateEventText(" Well done, you completed the second common objective and you gain " + points + " points...");
Game.waitForSeconds(Game.showTimer);
change = true;
}
}catch(Exception e){connectionLost(e);}
return change;
}
/**
* method that checks if the current player completed his library, and in that case notify all the other players (and add 1 point)
* @author Ettori
* @return true iff the library was completed
*/
private boolean checkLibFull(){
try {
if (library.isFull() && !endGame) {
try {
AudioInputStream audioInput = AudioSystem.getAudioInputStream(new BufferedInputStream(getClass().getResourceAsStream("/library.wav")));
Clip clip = AudioSystem.getClip();
clip.open(audioInput);
clip.start();
}catch(Exception e){
e.printStackTrace();
}
endGame = true;
pointsUntilNow++;
sendToServer(new Message(MessageType.LIB_FULL, name, null));
updateEventText(" Well done, you are the first player to complete the library, the game will continue until the next turn of " + chairmanName + "...");
updateBoard();
Game.waitForSeconds(Game.showTimer);
return true;
}
}catch (Exception e){connectionLost(e);}
return false;
}
/**
* helper method which update the board when it becomes unplayable (also notify other players)
* @author Ettori
*/
private void fixUnplayableBoard(){
board.fillBoard(numPlayers);
updateGUI();
updateEventText(" Board updated because it was unplayble");
try {
sendToServer(new Message(MessageType.UPDATE_UNPLAYABLE, name, new Board(board)));
}catch (Exception e){connectionLost(e);}
}
/**
* method that sends the last move done by the current player to all other clients (after the move is done on this player)
* @author Ettori
*/
private void sendDoneMove(){
updateEventText(" You made your move, now wait for other players to acknowledge it...");
sendToServer(new Message(MessageType.UPDATE_GAME, name, new PlayerSend(this)));
turnThread.interrupt();
}
/**
* Send with socket network the message of the chat to the right players
* @author Ettori
*/
public void sendChatMsg(){
String dest = insertPlayer.getText();
String msg = insertMessage.getText();
insertPlayer.setText("");
insertMessage.setText("");
msg = name + " says: " + msg + " (to " + dest + ") at " + new SimpleDateFormat("dd-MM-yyyy HH:mm:ss").format(new Date()) + "\n";
if(!doesPlayerExists(dest) && !dest.equals("all")) {
alert("\nThe name chosen does not exists");
return;
}
if(dest.equals(name)){
alert("\nYou can't send chat messages to yourself");
return;
}
fullChat += msg;
tempChatHistory.setText(fullChat);
try{
sendToServer(new Message(MessageType.CHAT, dest, msg));
}catch(Exception e){connectionLost(e);}
}
/**
* helper function for alerting a message to the user (pop-up)
* @param s the string or the message to show
*/
private void alert(String s){showMessageDialog(null, s);}
/**
* function that handle the eventual disconnection
* @param e the exception to throw
* @author Ettori
*/
public void connectionLost(Exception e){
if(closed)
return;
closed = true;
if(Player.showErrors)
throw new RuntimeException(e);
else
new Thread(() -> updateEventText(" The connection was lost and the application is disconnecting...")).start();
Game.waitForSeconds(Game.waitTimer);
System.out.println("\nThe connection was lost and the application is disconnecting...\n");
System.exit(0);
}
/**
* method that periodically pings the server from socket client
* @author Ettori
*/
public void ping(){
while(true){
Game.waitForSeconds(Game.waitTimer * 2);
try {
outStream.writeObject(new Message(MessageType.PING, null, null));
} catch (IOException e) {
connectionLost(e);
}
}
}
/**
* method that periodically pings the server from RMI client
* @author Ettori
*/
public void pingRMI(){
while(true){
Game.waitForSeconds(Game.waitTimer * 2);
try {
server.ping();
} catch (RemoteException e) {
connectionLost(e);
}
}
}
/******************************************** RMI ***************************************************************/
/**
* method (called from remote) that is the equivalent of wait for events of the socket version
* @param msg the message received from the server
* @author Ettori
*/
public void receivedEventRMI(Message msg){
switch (msg.getType()) {
case YOUR_TURN -> handleYourTurnEvent();
case CHANGE_TURN -> handleChangeTurnEvent(msg);
case UPDATE_UNPLAYABLE -> handleUpdateUnplayableEvent(msg);
case UPDATE_GAME -> handleUpdateGameEvent(msg);
case FINAL_SCORE -> handleFinalScoreEvent(msg);
case CHAT -> handleChatEvent(msg);
case CO_1 -> handleCO_1Event(msg);
case CO_2 -> handleCO_2Event(msg);
case LIB_FULL -> handleLibFullEvent(msg);
case DISCONNECTED -> handleDisconnectedEvent(msg);
case LOST_CLIENT -> handleLostClientEvent(msg);
case SHOW_EVENT -> handleShowEvent(msg);
}
}
/**
* general method to send a message to the server, it chooses the right network connection of the player
* @author Ettori
* @param msg the message that must be sent
*/
public void sendToServer(Message msg){
if(netMode == NetMode.SOCKET) {
try {
outStream.writeObject(msg);
} catch (IOException e) {
connectionLost(e);
}
}
else{
try {
server.redirectToClientRMI(msg);
} catch (RemoteException e) {
connectionLost(e);
}
}
}
/**
* method that listen for the final score of the game, for RMI clients
* @author Ettori
*/
private void listenForEndGame(){
Message msg = null;
while(true) {
try {
msg = (Message) inStream.readObject();
} catch (IOException | ClassNotFoundException e) {
connectionLost(e);
}
if (msg == null)
connectionLost(new NullPointerException());
if (msg.getType() != MessageType.FINAL_SCORE)
connectionLost(new RuntimeException("listenForEndGame method in GUI received a message different than FINAL_SCORE"));
handleFinalScoreEvent(msg);
}
}
/**
* method that allow the server ping the RMI client
* @author Ettori
*/
public void pingClient(){}
/**
* Function that initialize all the GUI
* @author Ettori Faccincani Giammusso
*/
public void initGUI(){
//general gbc
gbc.insets = new Insets(Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder);
//CYAN
//set the GUI of PO and CO
POLabel = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource(objective.imagePath)).getImage().getScaledInstance(Dimensions.PO_w, Dimensions.PO_h, Image.SCALE_SMOOTH)));
POLabel.setPreferredSize(new Dimension(Dimensions.PO_w, Dimensions.PO_h));
POPanel = new JPanel(new GridBagLayout());
POTitle = new JTextField(" Your private objective ");
POTitle.setMinimumSize(new Dimension(Dimensions.textCols * Dimensions.textCharsNum, Dimensions.textCols));
POTitle.setEditable(false);
POTitle.setBorder(null);
CO1Label = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource(board.commonObjective_1.imagePath)).getImage().getScaledInstance(Dimensions.CO_w, Dimensions.CO_h, Image.SCALE_SMOOTH)));
CO1Label.setLayout(null);
CO1Label.setPreferredSize(new Dimension(Dimensions.CO_w, Dimensions.CO_h));
CO1Panel = new JPanel(new GridBagLayout());
CO1Title = new JTextField(" The first common objective ");
CO1Title.setBorder(null);
CO1Title.setMinimumSize(new Dimension(Dimensions.textCols * Dimensions.textCharsNum, Dimensions.textCols));
CO1Title.setEditable(false);
CO2Label = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource(board.commonObjective_2.imagePath)).getImage().getScaledInstance(Dimensions.CO_w, Dimensions.CO_h, Image.SCALE_SMOOTH)));
CO2Label.setLayout(null);
CO2Label.setPreferredSize(new Dimension(Dimensions.CO_w, Dimensions.CO_h));
CO2Panel = new JPanel(new GridBagLayout());
CO2Title = new JTextField(" The second common objective ");
CO2Title.setBorder(null);
CO2Title.setMinimumSize(new Dimension(Dimensions.textCols * Dimensions.textCharsNum, Dimensions.textCols));
CO2Title.setEditable(false);
pointsCO1Label = new JLabel(new ImageIcon (new ImageIcon(classLoader.getResource("scoring tokens/scoring.jpg")).getImage().getScaledInstance(Dimensions.pointsDim, Dimensions.pointsDim, Image.SCALE_SMOOTH)));
pointsCO1Label.setPreferredSize(new Dimension(Dimensions.pointsDim, Dimensions.pointsDim));
pointsCO2Label = new JLabel(new ImageIcon (new ImageIcon(classLoader.getResource("scoring tokens/scoring.jpg")).getImage().getScaledInstance(Dimensions.pointsDim, Dimensions.pointsDim, Image.SCALE_SMOOTH)));
pointsCO2Label.setPreferredSize(new Dimension(Dimensions.pointsDim, Dimensions.pointsDim));
//GUI of chairman
chairmanLabel = new JLabel(isChairMan ? new ImageIcon (new ImageIcon(classLoader.getResource("misc/firstplayertoken.png")).getImage().getScaledInstance(Dimensions.chairmanDim, Dimensions.chairmanDim, Image.SCALE_SMOOTH)) : new ImageIcon (new ImageIcon(classLoader.getResource("misc/sfondo parquet.jpg")).getImage().getScaledInstance(Dimensions.chairmanDim, Dimensions.chairmanDim, Image.SCALE_SMOOTH)));
chairmanLabel.setPreferredSize(new Dimension(Dimensions.chairmanDim, Dimensions.chairmanDim));
chairmanPanel = new JPanel(new GridBagLayout());
chairmanTitle = new JTextField(" Chairman Icon ");
chairmanTitle.setBorder(null);
chairmanTitle.setMinimumSize(new Dimension(Dimensions.textCols * Dimensions.textCharsNum, Dimensions.textCols));
chairmanTitle.setEditable(false);
chairmanPanel.setVisible(isChairMan);
infoBox = new JPanel(new GridBagLayout());
chairmanInfo = new JTextField();
chairmanInfo.setText(" The chairman is " + chairmanName + " ");
chairmanInfo.setBorder(null);
chairmanInfo.setMinimumSize(new Dimension(Dimensions.textCols * (Dimensions.textCharsNum + 2), Dimensions.textCols));
chairmanInfo.setEditable(false);
activeTurnInfo = new JTextField();
activeTurnInfo.setBorder(null);
activeTurnInfo.setMinimumSize(new Dimension(Dimensions.textCols * (Dimensions.textCharsNum + 2), Dimensions.textCols));
activeTurnInfo.setEditable(false);
curPointsInfo = new JTextField();
curPointsInfo.setBorder(null);
curPointsInfo.setMinimumSize(new Dimension(Dimensions.textCols * (Dimensions.textCharsNum + 2), Dimensions.textCols));
curPointsInfo.setEditable(false);
titleInfo = new JTextField(" INFORMATIONS ABOUT THE GAME ");
titleInfo.setBorder(null);
titleInfo.setMinimumSize(new Dimension(Dimensions.textCols * (Dimensions.textCharsNum + 2), Dimensions.textCols));
titleInfo.setEditable(false);
//settings of the gbc of the right part of the GUI
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.25;
infoBox.add(titleInfo,gbc);
gbc.fill = HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.25;
infoBox.add(chairmanInfo,gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.25;
infoBox.add(activeTurnInfo,gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.25;
infoBox.add(curPointsInfo,gbc);
gbc.fill = NONE;
//SECOND LEVEL - CYAN
internalPanelSide = new JPanel(new GridBagLayout());
Insets insets = CO1Label.getInsets();
CO1Label.add(pointsCO1Label);
pointsCO1Label.setBounds(insets.left + 85, insets.top + 27, Dimensions.pointsDim, Dimensions.pointsDim);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.anchor = CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
CO1Panel.add(CO1Title, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0;
gbc.weighty = 0.9;
CO1Panel.add(CO1Label,gbc);
gbc.weighty = 0.2;
gbc.anchor = CENTER;
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 100;
gbc.insets = new Insets(25,0,0,0);
internalPanelSide.add(CO1Panel,gbc);
gbc.insets = new Insets(Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder);
insets = CO2Label.getInsets();
CO2Label.add(pointsCO2Label);
pointsCO2Label.setBounds(insets.left + 85, insets.top + 27, Dimensions.pointsDim, Dimensions.pointsDim);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.anchor = CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
CO2Panel.add(CO2Title, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0;
gbc.weighty = 0.9;
CO2Panel.add(CO2Label,gbc);
gbc.anchor = CENTER;
gbc.weighty = 0.2;
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 100;
internalPanelSide.add(CO2Panel,gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.anchor = CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
POPanel.add(POTitle, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0;
gbc.weighty = 0.9;
POPanel.add(POLabel,gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.ipadx = 0;
gbc.ipady = 100;
gbc.weighty = 0.2;
internalPanelSide.add(POPanel, gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.anchor = CENTER;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
chairmanPanel.add(chairmanTitle, gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0;
gbc.weighty = 0.9;
chairmanPanel.add(chairmanLabel,gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.ipadx = 0;
gbc.ipady = 100;
gbc.weighty = 0.2;
internalPanelSide.add(chairmanPanel, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.ipadx = 0;
gbc.ipady = 100;
gbc.weighty = 0.2;
gbc.weightx = 1.0;
gbc.insets = new Insets(0,0,25,0);
internalPanelSide.add(infoBox, gbc);
gbc.insets = new Insets(Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder);
gbc.weightx = 0.0;
//GREEN
//GUI of the other player
internalPanelLow = new JPanel(new GridBagLayout());
player1Panel = new JPanel(new GridBagLayout());
//Text
library1Text = new JTextArea(1, Dimensions.textCols * 2 / 3);
library1Text.setEditable(false);
//Library of the player 1
library1Label = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("boards/bookshelf_orth.png")).getImage().getScaledInstance(Dimensions.lib_w, Dimensions.lib_h, Image.SCALE_SMOOTH)));
library1Label.setLayout(null);
library1Label.setPreferredSize(new Dimension(Dimensions.lib_w, Dimensions.lib_h));
player2Panel = new JPanel(new GridBagLayout());
//Text
library2Text = new JTextArea(1, Dimensions.textCols * 2 / 3);
library2Text.setEditable(false);
//Library of the player 2
library2Label = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("boards/bookshelf_orth.png")).getImage().getScaledInstance(Dimensions.lib_w, Dimensions.lib_h, Image.SCALE_SMOOTH)));
library2Label.setLayout(null);
library1Label.setPreferredSize(new Dimension(Dimensions.lib_w, Dimensions.lib_h));
player3Panel = new JPanel(new GridBagLayout());
//Text
library3Text = new JTextArea(1, Dimensions.textCols * 2 / 3);
library3Text.setEditable(false);
//Library of the player 3
library3Label = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("boards/bookshelf_orth.png")).getImage().getScaledInstance(Dimensions.lib_w, Dimensions.lib_h, Image.SCALE_SMOOTH)));
library3Label.setLayout(null);
library1Label.setPreferredSize(new Dimension(Dimensions.lib_w, Dimensions.lib_h));
library1Text.setText(" Library of " + librariesOfOtherPlayers.get(0).name + " ");
if(numPlayers >= 3)
library2Text.setText(" Library of " + librariesOfOtherPlayers.get(1).name + " ");
if(numPlayers >= 4)
library3Text.setText(" Library of " + librariesOfOtherPlayers.get(2).name + " ");
if(numPlayers < 4)
player3Panel.setVisible(false);
if(numPlayers < 3)
player2Panel.setVisible(false);
JLabel tempLabel;
JPanel tempPanel;
insets = library1Label.getInsets();
// fill library
for(int i = 0; i < ROWS; i++){
for(int j = 0; j < COLS; j++){
tempLabel = new JLabel();
tempPanel = new JPanel();
tempLabel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempLabel.setVisible(false);
tempPanel.add(tempLabel);
tempPanel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempPanel.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel.setOpaque(false);
tempPanel.setBounds(insets.left + (Dimensions.cardLib_w * j) + 30 + (9 * j), insets.top + (Dimensions.cardLib_h * i) + 18 + (2 * i), Dimensions.cardLib_w, Dimensions.cardLib_h);
library1Label.add(tempPanel,gbc);
otherLibrariesCards.get(0)[i][j] = tempLabel;
}
}
insets = library2Label.getInsets();
// fill library
for(int i = 0; i < ROWS; i++){
for(int j = 0; j < COLS; j++){
tempLabel = new JLabel();
tempPanel = new JPanel();
tempLabel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempLabel.setVisible(false);
tempPanel.add(tempLabel);
tempPanel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempPanel.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel.setOpaque(false);
tempPanel.setBounds(insets.left + (Dimensions.cardLib_w * j) + 30 + (9 * j), insets.top + (Dimensions.cardLib_h * i) + 18 + (2 * i), Dimensions.cardLib_w, Dimensions.cardLib_h);
library2Label.add(tempPanel,gbc);
otherLibrariesCards.get(1)[i][j] = tempLabel;
}
}
insets = library3Label.getInsets();
// fill library
for(int i = 0; i < ROWS; i++){
for(int j = 0; j < COLS; j++){
tempLabel = new JLabel();
tempPanel = new JPanel();
tempLabel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempLabel.setVisible(false);
tempPanel.add(tempLabel);
tempPanel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempPanel.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel.setOpaque(false);
tempPanel.setBounds(insets.left + (Dimensions.cardLib_w * j) + 30 + (9 * j), insets.top + (Dimensions.cardLib_h * i) + 18 + (2 * i), Dimensions.cardLib_w, Dimensions.cardLib_h);
library3Label.add(tempPanel,gbc);
otherLibrariesCards.get(2)[i][j] = tempLabel;
}
}
//player 1
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.2;
player1Panel.add(library1Text,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.8;
player1Panel.add(library1Label,gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 100;
gbc.ipady = 0;
gbc.weightx = 0.1;
gbc.weighty = 0.0;
internalPanelLow.add(player1Panel,gbc);
//player 2
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.2;
player2Panel.add(library2Text,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.8;
player2Panel.add(library2Label,gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.ipadx = 100;
gbc.ipady = 0;
gbc.weightx = 0.1;
gbc.weighty = 0.0;
internalPanelLow.add(player2Panel,gbc);
//player 3
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.2;
player3Panel.add(library3Text,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.8;
player3Panel.add(library3Label,gbc);
gbc.gridx = 2;
gbc.gridy = 0;
gbc.ipadx = 100;
gbc.ipady = 0;
gbc.weightx = 0.1;
gbc.weighty = 0.0;
internalPanelLow.add(player3Panel,gbc);
//panel on the bottom of the GUI with the last event
eventText = new JTextField(120);
updateEventText(" Last relevant event of the Game ");
eventText.setMinimumSize(new Dimension(Dimensions.textCols * 45, Dimensions.textCols + 8));
eventText.setEditable(false);
eventText.setBorder(null);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1;
gbc.weighty = 0.2;
gbc.gridwidth = 3;
gbc.insets = new Insets(0,15,10,0);
internalPanelLow.add(eventText, gbc);
//BLUE
//GUI of the board
internalPanelHigh = new JPanel(new GridBagLayout());
gameBoardPanel = new JPanel(new GridBagLayout()); //the chairman is just a card in the matrix
//Text on top of the board
boardText = new JTextArea(" Board of the Game ");
boardText.setEditable(false);
boardLabel = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("boards/livingroom.png")).getImage().getScaledInstance(Dimensions.boardDim, Dimensions.boardDim, Image.SCALE_SMOOTH)));
boardLabel.setPreferredSize(new Dimension(Dimensions.boardDim, Dimensions.boardDim));
boardLabel.setLayout(new GridBagLayout());
// fill the board
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++){
tempLabel = new JLabel();
tempPanel = new JPanel();
tempLabel.setPreferredSize(new Dimension(Dimensions.cardDimBoard, Dimensions.cardDimBoard));
tempLabel.setVisible(false);
gbc.insets = new Insets(0,0,0,0);
gbc.gridx = j;
gbc.gridy = i;
gbc.ipadx = 2;
gbc.ipady = 2;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
gbc.gridwidth = 1;
gbc.gridheight = 1;
if(i == libFullX && j == libFullY) {
tempPanel.setLayout(null);
gbc.gridwidth = 2;
gbc.gridheight = 2;
}
tempPanel.add(tempLabel);
tempPanel.setPreferredSize(new Dimension(Dimensions.cardDimBoard, Dimensions.cardDimBoard));
tempPanel.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel.setOpaque(false);
boardLabel.add(tempPanel,gbc);
if(i == libFullX && j == libFullY){
insets = tempPanel.getInsets();
tempLabel.setBounds(insets.left + 4, insets.top, Dimensions.cardDimBoard, Dimensions.cardDimBoard);
}
boardCards[i][j] = tempLabel;
}
}
for(int i = 0; i < DIM; i++){
for(int j = 0; j < DIM; j++){
int finalI = i;
int finalJ = j;
boardCards[i][j].addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(board.getGameBoard()[finalI][finalJ].color == it.polimi.ingsw.model.Color.EMPTY || !name.equals(activeName) || board.isBoardUnplayable())
return;
int index = getCardIndex(finalI, finalJ);
if(index == -1){
if(cardsPicked.size() == 6)
return;
boardCards[finalI][finalJ].setBorder(BorderFactory.createLineBorder(borderColor, cardBorderSize));
cardsPicked.add(finalI);
cardsPicked.add(finalJ);
}
else{
boardCards[finalI][finalJ].setBorder(BorderFactory.createLineBorder(borderColor, 0));
cardsPicked.remove(index);
cardsPicked.remove(index);
}
}
});
}
}
boardCards[libFullX][libFullY].setIcon(new ImageIcon(new ImageIcon(classLoader.getResource("scoring tokens/end game.jpg")).getImage().getScaledInstance(Dimensions.cardDimBoard, Dimensions.cardDimBoard, Image.SCALE_SMOOTH)));
gbc.insets = new Insets(Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder);
//GUI of my library
myLibraryPanel = new JPanel(new GridBagLayout());
//Text on top of my library
myLibraryText = new JTextArea(" Your personal Library (" + name + ") ");
myLibraryText.setEditable(false);
chooseColPanel = new JPanel(new FlowLayout());
r1 = new JRadioButton("col 1");
r2 = new JRadioButton("col 2");
r3 = new JRadioButton("col 3");
r4 = new JRadioButton("col 4");
r5 = new JRadioButton("col 5");
r1.setSelected(true);
btnGroup = new ButtonGroup();
btnGroup.add(r1);
btnGroup.add(r2);
btnGroup.add(r3);
btnGroup.add(r4);
btnGroup.add(r5);
chooseColPanel.add(r1);
chooseColPanel.add(r2);
chooseColPanel.add(r3);
chooseColPanel.add(r4);
chooseColPanel.add(r5);
pickCardsBtn = new JButton("Pick Cards");
pickCardsBtn.setFocusPainted(false);
pickCardsBtn.setPreferredSize(new Dimension(Dimensions.btnW, Dimensions.btnH));
pickCardsBtn.addActionListener(e -> new Thread(this::tryToPickCards).start());
libraryLabel = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("boards/bookshelf_orth.png")).getImage().getScaledInstance(Dimensions.lib_w, Dimensions.lib_h, Image.SCALE_SMOOTH)));
libraryLabel.setPreferredSize(new Dimension(Dimensions.lib_w, Dimensions.lib_h));
libraryLabel.setLayout(null);
insets = libraryLabel.getInsets();
// fill library
for(int i = 0; i < ROWS; i++){
for(int j = 0; j < COLS; j++){
tempLabel = new JLabel();
tempPanel = new JPanel();
tempLabel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempLabel.setVisible(false);
tempPanel.add(tempLabel);
tempPanel.setPreferredSize(new Dimension(Dimensions.cardLib_w, Dimensions.cardLib_h));
tempPanel.setBackground(new java.awt.Color(0, 0, 0, 0));
tempPanel.setOpaque(false);
tempPanel.setBounds(insets.left + (Dimensions.cardLib_w * j) + 30 + (9 * j), insets.top + (Dimensions.cardLib_h * i) + 18 + (2 * i), Dimensions.cardLib_w, Dimensions.cardLib_h);
libraryLabel.add(tempPanel,gbc);
myLibraryCards[i][j] = tempLabel;
}
}
//GUI of the chat
gbc.insets = new Insets(Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder, Dimensions.generalBorder);
chatPanel = new JPanel(new GridBagLayout());
chatTitle = new JTextArea(" Chat history of the Game ");
chatTitle.setEditable(false);
tempChatHistory = new JTextArea(Dimensions.textCols, Dimensions.textCols - 8);
tempChatHistory.setMinimumSize(new Dimension(Dimensions.textCols * (Dimensions.textCharsNum), Dimensions.textCols * (Dimensions.textCharsNum)));
tempChatHistory.setEditable(false);
tempChatHistory.setText(fullChat);
chatHistory = new JScrollPane(tempChatHistory);
chatHistory.setMinimumSize(new Dimension(Dimensions.textCols * (Dimensions.textCharsNum), Dimensions.textCols * (Dimensions.textCharsNum)));
insertMessage = new JTextField(Dimensions.textCols);
insertMessage.setMinimumSize(new Dimension(Dimensions.textCols * Dimensions.textCharsNum, Dimensions.textCols));
insertMessage.setText("Insert message: ");
insertMessage.setBorder(null);
insertMessage.addActionListener(event -> sendMessageBtn.doClick());
insertPlayer = new JTextField(Dimensions.textCols);
insertPlayer.setBorder(null);
insertPlayer.setText("Insert player (all for everyone) : ");
insertPlayer.setMinimumSize(new Dimension(Dimensions.textCols * Dimensions.textCharsNum, Dimensions.textCols));
sendMessageBtn = new JButton("Send Message");
sendMessageBtn.setFocusPainted(false);
sendMessageBtn.setPreferredSize(new Dimension());
sendMessageBtn.setPreferredSize(new Dimension(Dimensions.btnW, Dimensions.btnH));
sendMessageBtn.addActionListener(e -> new Thread(this::sendChatMsg).start());
//BOARD
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.1;
gameBoardPanel.add(boardText,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.9;
gameBoardPanel.add(boardLabel,gbc);
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.5;
gbc.weighty = 0.0;
internalPanelHigh.add(gameBoardPanel,gbc);
//LIBRARY
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.1;
myLibraryPanel.add(myLibraryText,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.6;
myLibraryPanel.add(libraryLabel,gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.6;
gbc.weighty = 0.15;
myLibraryPanel.add(chooseColPanel,gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.15;
myLibraryPanel.add(pickCardsBtn,gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.25;
internalPanelHigh.add(myLibraryPanel,gbc);
//CHAT
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.0;
chatPanel.add(chatTitle,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.5;
chatPanel.add(chatHistory,gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
chatPanel.add(insertPlayer,gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 1.0;
gbc.weighty = 0.1;
chatPanel.add(insertMessage,gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.2;
gbc.weighty = 0.0;
chatPanel.add(sendMessageBtn,gbc);
gbc.gridx = 2;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.0;
gbc.weighty = 0.25;
internalPanelHigh.add(chatPanel,gbc);
//FIRST LEVEL - RED
generalLabel = new JLabel(new ImageIcon(new ImageIcon(classLoader.getResource("misc/sfondo parquet.jpg")).getImage().getScaledInstance(screenSize.width * 5 / 6, screenSize.height * 9 / 10, Image.SCALE_SMOOTH)));
generalLabel.setPreferredSize(new Dimension(screenSize.width * 5 / 6, screenSize.height * 8 / 10 + 65));
generalLabel.setLayout(new GridBagLayout());
internalPanelHigh.setBackground(new Color(0, 0, 0, 0));
internalPanelSide.setBackground(new Color(0, 0, 0, 0));
internalPanelLow.setBackground(new Color(0, 0, 0, 0));
CO1Panel.setBackground(new Color(0, 0, 0, 0));
CO2Panel.setBackground(new Color(0, 0, 0, 0));
POPanel.setBackground(new Color(0, 0, 0, 0));
chairmanPanel.setBackground(new Color(0, 0, 0, 0));
player1Panel.setBackground(new Color(0, 0, 0, 0));
player2Panel.setBackground(new Color(0, 0, 0, 0));
player3Panel.setBackground(new Color(0, 0, 0, 0));
gbc.gridx = 0;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.8;
gbc.weighty = 0.5;
generalLabel.add(internalPanelHigh,gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.8;
gbc.weighty = 0.3;
generalLabel.add(internalPanelLow,gbc);
gbc.gridx = 1;
gbc.gridy = 0;
gbc.ipadx = 0;
gbc.ipady = 0;
gbc.weightx = 0.2;
gbc.weighty = 0.8;
gbc.gridheight = 2;
generalLabel.add(internalPanelSide,gbc);
//remove all the precedent GUI used to choose the name
mainPanel.removeAll();
//Now add the new GUI to play the game
gbc2.gridx=0;
gbc2.gridy=0;
mainPanel.add(generalLabel,gbc2);
mainFrame.setVisible(true);
mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
mainFrame.addWindowListener(new java.awt.event.WindowAdapter() {
@Override
public void windowClosing(java.awt.event.WindowEvent windowEvent) {
if (JOptionPane.showConfirmDialog(mainFrame, "Are you sure to close the game ? (progress will be saved)", "Close Window", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION)
System.exit(0);
}
});
Game.waitForSeconds(Game.fastTimer);
new Thread(this::updateGUI).start();
}
}