Coverage Summary for Class: PlayerBoardPanel (it.polimi.ingsw.Client.GUI.Panels)

Class Method, % Branch, % Line, %
PlayerBoardPanel 0% (0/8) 0% (0/113) 0% (0/252)
PlayerBoardPanel$1 0% (0/1) 0% (0/2)
Total 0% (0/9) 0% (0/113) 0% (0/254)


1 package it.polimi.ingsw.Client.GUI.Panels; 2  3 import it.polimi.ingsw.Client.GUI.ActionType; 4 import it.polimi.ingsw.Client.GUI.Components.StudentButton; 5 import it.polimi.ingsw.Client.GUI.Listeners.CheckBoxListener; 6 import it.polimi.ingsw.Client.GUI.Listeners.GUISocketListener; 7 import it.polimi.ingsw.Controller.Actions.MoveStudent; 8 import it.polimi.ingsw.Controller.Actions.PlayAssistantCard; 9 import it.polimi.ingsw.Controller.Actions.PlayCharacterCard; 10 import it.polimi.ingsw.Controller.MoveDestination; 11 import it.polimi.ingsw.Misc.OptionalValue; 12 import it.polimi.ingsw.Misc.Pair; 13 import it.polimi.ingsw.Model.*; 14 import it.polimi.ingsw.Model.Enums.GameMode; 15 import it.polimi.ingsw.Model.Enums.PawnColour; 16 import it.polimi.ingsw.Network.SocketWrapper; 17 import it.polimi.ingsw.Server.Messages.Events.Requests.PlayerActionRequest; 18  19 import javax.swing.*; 20 import java.awt.*; 21 import java.io.IOException; 22 import java.util.List; 23 import java.util.*; 24 import java.util.stream.Collectors; 25  26 import static it.polimi.ingsw.Client.GUI.IconLoader.*; 27  28 /** 29  * Class containing all the elements necessary to graphically represent both the player’s playerBoard and the assistant cards still usable. It also implements 30  * some logic of characterCard's actions which require to interact with the playerboard in order to work properly. 31  */ 32 public class PlayerBoardPanel extends JPanel { 33  34  /** 35  * SocketWrapper necessary to send actions from GUI to server 36  */ 37  private final SocketWrapper socketWrapper; 38  39  /** 40  * Contains player's PlayerBoard information 41  */ 42  private final PlayerBoard player; 43  44  /** 45  * Contains game's information 46  */ 47  private final Model model; 48  49  /** 50  * Contains GuiReader's information necessary to record user's requests during his turn 51  */ 52  private final GUISocketListener guiSocketListener; 53  54  /** 55  * Create a new PlayerBoardPanel 56  * 57  * @param pb Player's playerboard to represent 58  * @param model Game's model 59  * @param socketWrapper socketWrapper to communicate with Server 60  * @param guiSocketListener guiReader from GameInProgressPanel 61  */ 62  public PlayerBoardPanel(PlayerBoard pb, Model model, SocketWrapper socketWrapper, GUISocketListener guiSocketListener) { 63  this.player = pb; 64  this.guiSocketListener = guiSocketListener; 65  this.socketWrapper = socketWrapper; 66  this.model = model; 67  //list containing teachers owned by the player 68  List<PawnColour> teachers = model.getOwnTeachers(this.player); 69  //towerStorage owned by the player 70  TowerStorage towerStorage = model.getTeamMapper().getMutableTowerStorage(this.player); 71  //Get current player 72  TurnOrder turnOrder = model.getMutableTurnOrder(); 73  //create List that will contain assistantCards' buttons 74  ArrayList<JButton> assistantCardsLabels = new ArrayList<>(10); 75  //create List that will contain Entrance's students' buttons 76  ArrayList<JButton> entranceStudentsButton = new ArrayList<>(this.player.getEntranceSize()); 77  //create List that will contain Towers' labels 78  ArrayList<JLabel> towersLabels = new ArrayList<>(towerStorage.getTowerCount()); 79  //Map that associates every pawnColour to an arrayList of JButton 80  Map<PawnColour, ArrayList<JButton>> diningRoomButtons = new EnumMap<>(PawnColour.class); 81  //Contains assistantCards' buttons 82  JPanel assistantCardsPanel = new JPanel(); 83  assistantCardsPanel.setLayout(new FlowLayout(FlowLayout.LEFT)); 84  //create label containing coin amount 85  86  //initialize diningRoomButtons' map 87  for (PawnColour p : PawnColour.values()) { 88  diningRoomButtons.put(p, new ArrayList<>(this.player.getDiningRoomCount(p))); 89  } 90  //Basing on towerStorage's colour, labels contained by towersLabels have different images 91  for (int i = 0; i < towerStorage.getTowerCount(); i++) { 92  switch (towerStorage.getColour()) { 93  case GRAY -> towersLabels.add(new JLabel(GrayTower)); 94  case BLACK -> towersLabels.add(new JLabel(BlackTower)); 95  case WHITE -> towersLabels.add(new JLabel(WhiteTower)); 96  } 97  } 98  //Draw students inside diningRoom 99  for (PawnColour p : diningRoomButtons.keySet()) { 100  for (int i = 0; i < this.player.getDiningRoomCount(p); i++) { 101  //Basing on pawnColour, labels have different images 102  switch (p) { 103  case RED -> diningRoomButtons.get(p).add(new StudentButton(PawnColour.RED, 1, false)); 104  case GREEN -> diningRoomButtons.get(p).add(new StudentButton(PawnColour.GREEN, 1, false)); 105  case YELLOW -> diningRoomButtons.get(p).add(new StudentButton(PawnColour.YELLOW, 1, false)); 106  case BLUE -> diningRoomButtons.get(p).add(new StudentButton(PawnColour.BLUE, 1, false)); 107  case PINK -> diningRoomButtons.get(p).add(new StudentButton(PawnColour.PINK, 1, false)); 108  } 109  //Remove borders and filling from every button 110  diningRoomButtons.get(p).get(diningRoomButtons.get(p).size() - 1).setBorderPainted(false); 111  diningRoomButtons.get(p).get(diningRoomButtons.get(p).size() - 1).setContentAreaFilled(false); 112  diningRoomButtons.get(p).get(diningRoomButtons.get(p).size() - 1).setFocusPainted(false); 113  diningRoomButtons.get(p).get(diningRoomButtons.get(p).size() - 1).setOpaque(false); 114  } 115  } 116  //Draw students inside entrance 117  for (int i = 0; i < this.player.getEntranceSize(); i++) { 118  if (this.player.getEntranceStudents().get(i).isEmpty()) { 119  entranceStudentsButton.add(new JButton("")); 120  entranceStudentsButton.get(i).setVisible(false); 121  continue; 122  } 123  switch (this.player.getEntranceStudents().get(i).get()) { 124  //Basing on pawnColour, labels have different images 125  case RED -> entranceStudentsButton.add(new StudentButton(PawnColour.RED, 1, false)); 126  case GREEN -> entranceStudentsButton.add(new StudentButton(PawnColour.GREEN, 1, false)); 127  case YELLOW -> entranceStudentsButton.add(new StudentButton(PawnColour.YELLOW, 1, false)); 128  case BLUE -> entranceStudentsButton.add(new StudentButton(PawnColour.BLUE, 1, false)); 129  case PINK -> entranceStudentsButton.add(new StudentButton(PawnColour.PINK, 1, false)); 130  } 131  //Remove borders and filling from every button 132  entranceStudentsButton.get(i).setBorderPainted(false); 133  entranceStudentsButton.get(i).setContentAreaFilled(false); 134  entranceStudentsButton.get(i).setFocusPainted(false); 135  entranceStudentsButton.get(i).setOpaque(false); 136  int finalI = i; 137  //add on-click action listener to Entrance's students' buttons 138  entranceStudentsButton.get(i).addActionListener(e -> { 139  // skip execution of the action if a previous action still hasn't been processed by the server 140  if (guiSocketListener.awaitingPlayerActionFeedback()) { 141  JOptionPane.showMessageDialog(null, "Please wait for the server to process your previous" + 142  "request before making a new one"); 143  return; 144  } 145  //create options that will be displayed on JOptionPane 146  String[] buttons = {"DiningRoom", "Island"}; 147  //create and show JoptionPane 148  int returnValue = JOptionPane.showOptionDialog(null, "Where do you want to send this pawn?", "Destination ", JOptionPane.DEFAULT_OPTION, 149  JOptionPane.QUESTION_MESSAGE, null, buttons, buttons[0]); 150  Container c = this.getParent(); 151  while (!(c instanceof JTabbedPane jTabbedPane)) { 152  //get JTabbedPane 153  c = c.getParent(); 154  } 155  //if user clicked first button (DiningRoom) 156  if (returnValue == 0) { 157  //create and send moveStudent action 158  MoveStudent moveStudent = new MoveStudent(this.player.getId(), finalI, MoveDestination.toDiningRoom()); 159  PlayerActionRequest playerAction = new PlayerActionRequest(moveStudent); 160  this.guiSocketListener.savePlayerActionRequest(moveStudent); 161  try { 162  socketWrapper.sendMessage(playerAction); 163  } catch (IOException ex) { 164  throw new RuntimeException(ex); 165  } 166  } else if (returnValue == 1) { //if the user clicked second button (Island) 167  //switch jTabbedPane to first tab 168  jTabbedPane.setSelectedIndex(0); 169  //get IslandFieldPanel 170  IslandFieldPanel islandFieldPanel = (IslandFieldPanel) jTabbedPane.getSelectedComponent(); 171  //Set correct actionType inside islandFieldPanel 172  islandFieldPanel.setActionType(ActionType.MOVESTUDENT, OptionalValue.of(finalI)); 173  } 174  }); 175  } 176  177  ArrayList<JButton> assistantCardsButtonsToShow; 178  //label containing all others elements 179  JLabel boardBackground = new JLabel(playerBoardBackground); 180  //label containing PlayerBoard 181  JLabel playerBoardLabel = new JLabel(playerBoard); 182  //----labels containing assistantCards---- 183  ArrayList<ImageIcon> assistantCardsIcon = new ArrayList<>(Arrays.asList(assistantCard1, assistantCard2, assistantCard3, assistantCard4, assistantCard5, assistantCard6, assistantCard7, assistantCard8, assistantCard9, assistantCard10)); 184  ArrayList<JButton> assistantCardsButtons = new ArrayList<>(10); 185  for (int i = 0; i < 10; i++) { 186  //create assistantCard's button 187  JButton assistantCardButton = new JButton(assistantCardsIcon.get(i)); 188  int finalI = i + 1; 189  //add on-click actionListener to assistantCard's button 190  assistantCardButton.addActionListener(e -> { 191  // skip execution of the action if a previous action still hasn't been processed by the server 192  if (guiSocketListener.awaitingPlayerActionFeedback()) { 193  JOptionPane.showMessageDialog(null, "Please wait for the server to process your previous" + 194  "request before making a new one"); 195  return; 196  } 197  //enable button only if a playAssistantCard action has not been played 198  if (guiSocketListener.getSuccessfulRequestsByType(PlayAssistantCard.class) == 0) { 199  int dialogButton = JOptionPane.YES_NO_OPTION; 200  //create optionPane for confirmation 201  int dialogResult = JOptionPane.showConfirmDialog(this, "Confirm to play assistant card with priority: " + finalI + "?", "PlayAssistant card confirmation", dialogButton); 202  if (dialogResult == 0) { 203  //if the player clicked first button (YES) then create and send the playAssistantCard action 204  PlayAssistantCard playAssistantCard = new PlayAssistantCard(this.player.getId(), finalI); 205  PlayerActionRequest playerAction = new PlayerActionRequest(playAssistantCard); 206  this.guiSocketListener.savePlayerActionRequest(playAssistantCard); 207  try { 208  socketWrapper.sendMessage(playerAction); 209  } catch (IOException ex) { 210  throw new RuntimeException(ex); 211  } 212  } 213  } 214  }); 215  //add assistantCard's button to assistantCardsButtons arrayList 216  assistantCardsButtons.add(assistantCardButton); 217  } 218  //----labels containing Teachers---- 219  JLabel redTeacherLabel = new JLabel(RedTeacher); 220  JLabel blueTeacherLabel = new JLabel(BlueTeacher); 221  JLabel pinkTeacherLabel = new JLabel(PinkTeacher); 222  JLabel greenTeacherLabel = new JLabel(GreenTeacher); 223  JLabel yellowTeacherLabel = new JLabel(YellowTeacher); 224  //add all assistantcardLabels to support ArrayList 225  assistantCardsLabels.addAll(assistantCardsButtons); 226  //get unused assistantCards 227  ArrayList<AssistantCard> availableAssistants = this.player.getMutableAssistantCards() 228  .stream().filter(assistantCard -> !assistantCard.getUsed()) 229  .collect(Collectors.toCollection(ArrayList::new)); 230  //from the unused cards, extract the card with a priority not selected before by other players 231  for (PlayerBoard p : turnOrder.getCurrentTurnOrder()) { 232  if (turnOrder.getMutableSelectedCard(p).isPresent()) { 233  availableAssistants.removeIf(assistantCard -> assistantCard.getPriority() == turnOrder.getMutableSelectedCard(p).get().getPriority()); 234  } 235  } 236  assistantCardsButtonsToShow = GetCardsToShow(assistantCardsLabels, availableAssistants); 237  //Remove borders and filling from every button 238  assistantCardsButtonsToShow.forEach(jButton -> { 239  jButton.setBorderPainted(false); 240  jButton.setContentAreaFilled(false); 241  jButton.setFocusPainted(false); 242  jButton.setOpaque(false); 243  //jButton.addActionListener(e -> playAssistantCard(e)); 244  } 245  ); 246  247  assistantCardsPanel.setPreferredSize(new Dimension(assistantCardsButtonsToShow.size() * 205, 250)); 248  //add Panel containing assistantCards as parameter for JScrollPane's constructor 249  JScrollPane assistantCardsScrollPane = new JScrollPane(assistantCardsPanel); 250  //remove JScrollPane's borders 251  assistantCardsScrollPane.setBorder(BorderFactory.createEmptyBorder()); 252  assistantCardsScrollPane.setOpaque(false); 253  assistantCardsScrollPane.getViewport().setOpaque(false); 254  //remove assistantCardsPanel's background 255  assistantCardsPanel.setOpaque(false); 256  //hide Teachers' labels 257  redTeacherLabel.setVisible(false); 258  blueTeacherLabel.setVisible(false); 259  greenTeacherLabel.setVisible(false); 260  yellowTeacherLabel.setVisible(false); 261  pinkTeacherLabel.setVisible(false); 262  //show PlayerBoard's teachers 263  for (PawnColour p : teachers) { 264  switch (p) { 265  case RED -> redTeacherLabel.setVisible(true); 266  case GREEN -> greenTeacherLabel.setVisible(true); 267  case YELLOW -> yellowTeacherLabel.setVisible(true); 268  case BLUE -> blueTeacherLabel.setVisible(true); 269  case PINK -> pinkTeacherLabel.setVisible(true); 270  } 271  } 272  //---ABSOLUTE POSITIONING---- 273  boardBackground.setBounds(0, 0, 1080, 720); 274  playerBoardLabel.setBounds(0, 0, 1080, 420); 275  redTeacherLabel.setBounds(765, 120, 50, 45); 276  greenTeacherLabel.setBounds(765, 50, 50, 45); 277  yellowTeacherLabel.setBounds(765, 185, 50, 45); 278  pinkTeacherLabel.setBounds(765, 257, 50, 45); 279  blueTeacherLabel.setBounds(765, 325, 50, 45); 280  //create and place a label containing player balance (only if the game is an advanced game) 281  if (model.getGameMode() == GameMode.ADVANCED) { 282  JLabel coinAmountLabel = new JLabel(); 283  String text; 284  if (pb.getCoinBalance() > 1) { 285  text = "available coins:" + pb.getCoinBalance(); 286  } else { 287  text = "Available coin:" + pb.getCoinBalance(); 288  } 289  coinAmountLabel.setText(text); 290  coinAmountLabel.setOpaque(true); 291  coinAmountLabel.setBackground(new Color(195, 193, 204)); 292  coinAmountLabel.setBounds(850, 10, 200, 25); 293  coinAmountLabel.setFont(new Font("Monospaced", Font.BOLD, 17)); 294  playerBoardLabel.add(coinAmountLabel); 295  } 296  int count = 0; 297  int secondCount = 0; 298  for (int i = 0; i < this.player.getEntranceSize(); i++) { 299  if (i % 2 == 0) { 300  entranceStudentsButton.get(i).setBounds(90, 50 + 70 * count, 60, 45); 301  count++; 302  } else { 303  entranceStudentsButton.get(i).setBounds(25, 123 + 70 * (secondCount), 60, 45); 304  secondCount++; 305  } 306  } 307  count = 0; 308  secondCount = 0; 309  for (int i = 0; i < towerStorage.getTowerCount(); i++) { 310  if (i % 2 == 0) { 311  towersLabels.get(i).setBounds(880, 50 + 70 * count, 50, 75); 312  count++; 313  } else { 314  towersLabels.get(i).setBounds(965, 50 + 70 * secondCount, 50, 75); 315  secondCount++; 316  } 317  } 318  319  for (PawnColour p : diningRoomButtons.keySet()) { 320  count = 0; 321  for (int i = 0; i < this.player.getDiningRoomCount(p); i++) { 322  switch (p) { 323  case RED -> diningRoomButtons.get(p).get(i).setBounds(200 + 50 * count, 120, 50, 45); 324  case GREEN -> diningRoomButtons.get(p).get(i).setBounds(200 + 50 * count, 50, 50, 45); 325  case YELLOW -> diningRoomButtons.get(p).get(i).setBounds(200 + 50 * count, 190, 50, 45); 326  case BLUE -> diningRoomButtons.get(p).get(i).setBounds(200 + 50 * count, 330, 50, 45); 327  case PINK -> diningRoomButtons.get(p).get(i).setBounds(200 + 50 * count, 260, 50, 45); 328  } 329  count++; 330  } 331  } 332  333  assistantCardsScrollPane.setBounds(0, 430, 1080, 290); 334  //add boardBackground's panel to window 335  this.add(boardBackground); 336  //add playerBoard's label to boardBackground's label 337  boardBackground.add(playerBoardLabel); 338  //add every assistant card to assistantCards' panel 339  assistantCardsButtonsToShow.forEach(assistantCardsPanel::add); 340  //add JScrollPane to boardBackground's label 341  boardBackground.add(assistantCardsScrollPane); 342  //add every entrance's student to PlayerBoard's label 343  entranceStudentsButton.forEach(playerBoardLabel::add); 344  //add every Tower's label to PlayerBoard's label 345  towersLabels.forEach(playerBoardLabel::add); 346  //add teachers' labels to PlayerBoard's label 347  playerBoardLabel.add(redTeacherLabel); 348  playerBoardLabel.add(blueTeacherLabel); 349  playerBoardLabel.add(greenTeacherLabel); 350  playerBoardLabel.add(yellowTeacherLabel); 351  playerBoardLabel.add(pinkTeacherLabel); 352  //add diningRoom's students' labels to PlayerBoard's label 353  for (PawnColour p : diningRoomButtons.keySet()) { 354  diningRoomButtons.get(p).forEach(playerBoardLabel::add); 355  } 356  } 357  358  /** 359  * Support method that, given an ArrayList of assistantCards, returns an arrayList containing the relative buttons 360  * (example, given the assistantCard with priority 5, the method returns a JButton with the right assistantCard's image (image with number 5) 361  * 362  * @param assistantCardsLabels ArrayList containing assistantCard's JButton (containing assistantCards' images) 363  * @param assistantCards ArrayList containing AssistantCards of interest 364  * @return an arrayList containing AssistantCards' JButtons 365  */ 366  private ArrayList<JButton> GetCardsToShow(ArrayList<JButton> assistantCardsLabels, ArrayList<AssistantCard> assistantCards) { 367  ArrayList<JButton> assistantsToShow = new ArrayList<>(assistantCards.size()); 368  for (AssistantCard assistantCard : assistantCards) { 369  assistantsToShow.add(assistantCardsLabels.get(assistantCard.getPriority() - 1)); 370  } 371  return assistantsToShow; 372  } 373  374  /** 375  * get PlayerBoardNickname 376  * 377  * @return playerBoardPanel's playerBoard's nickname 378  */ 379  public String getPlayerBoardNickname() { 380  return this.player.getNickname(); 381  } 382  383  /** 384  * get PlayerBoard id 385  * 386  * @return playerBoardPanel's playerBoard's id 387  */ 388  public int getPlayerBoardId() { 389  return this.player.getId(); 390  } 391  392  /** 393  * Executes characterCards' effects that interact directly with the playerBoard 394  * 395  * @param cardIndex card's priority 396  * @param cardPositionInGame card's position inside the game (0 to 2) 397  * @param fromCard Optional list containing pawnColour picked from characterCard 398  */ 399  public void PlayCharacterCardEffect(int cardIndex, int cardPositionInGame, OptionalValue<ArrayList<PawnColour>> fromCard) { 400  PlayCharacterCard playCharacterCard = null; 401  PlayerActionRequest playerActionRequest = null; 402  //create list that will contain chosen pawns from entrance 403  List<PawnColour> pawnsFromEntrance = new ArrayList<>(); 404  //create checkboxes that will allow user to select pawns from entrance 405  JCheckBox[] checkBoxes = new JCheckBox[player.getEntranceSize() - player.getEntranceSpaceLeft()]; 406  CheckBoxListener checkBoxListener; 407  //initialize checkboxes' limit basing on characterCard that has been selected 408  if (cardIndex == 7) { 409  checkBoxListener = new CheckBoxListener(fromCard.get().size(), checkBoxes); 410  } else { 411  checkBoxListener = new CheckBoxListener(2, checkBoxes); 412  } 413  int countboxes = 0; 414  //create JPanel that will be displayed by JoptionPane 415  JPanel optionPanel = new JPanel(); 416  for (int j = 0; j < player.getEntranceSize(); j++) { 417  //scan entrance and add a new CheckBox for every present pawn 418  if (player.getEntranceStudents().get(j).isPresent()) { 419  //create and add a new checkBox containing PawnColour's string 420  checkBoxes[countboxes] = new JCheckBox(player.getEntranceStudents().get(j).get().toString()); 421  //add checkBoxListener to the new checkBox 422  checkBoxes[countboxes].addItemListener(checkBoxListener); 423  optionPanel.add(checkBoxes[countboxes]); 424  countboxes++; 425  } 426  } 427  //create and show JOptionPane 428  int result = JOptionPane.showConfirmDialog(this, optionPanel, 429  "Select pawns from entrance", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 430  //if user selected 'cancel' or closed JOptionPane 431  if (result == -1 || result == 2) return; 432  for (JCheckBox checkBox : checkBoxes) { 433  if (checkBox.isSelected()) { 434  //add selected checBoxes pawn to pawnsFromEntrance list 435  pawnsFromEntrance.add(PawnColour.getPawnColourFromText(checkBox.getText())); 436  } 437  } 438  switch (cardIndex) { 439  case 7 -> { 440  //list that will contain Pawns' pairs (from entrance and CharacterCard) 441  ArrayList<Pair<PawnColour, PawnColour>> pairs = new ArrayList<>(fromCard.get().size()); 442  for (int i = 0; i < pawnsFromEntrance.size(); i++) { 443  //create and add a new Pair 444  pairs.add(new Pair<>(pawnsFromEntrance.get(i), fromCard.get().get(i))); 445  } 446  //create a new PlayCharacterCard action and its playerActionRequest 447  playCharacterCard = new PlayCharacterCard(model.getMutableTurnOrder().getMutableCurrentPlayer().getId(), 448  cardPositionInGame, OptionalValue.empty(), OptionalValue.empty(), OptionalValue.of(pairs)); 449  playerActionRequest = new PlayerActionRequest(playCharacterCard); 450  } 451  case 10 -> { 452  //Map containing playerBoard's diningRoom 453  Map<PawnColour, Integer> diningRoomCount = player.getDiningRoom(); 454  optionPanel = new JPanel(); 455  optionPanel.setLayout(new FlowLayout()); 456  //list containing JSpinners 457  ArrayList<JSpinner> jSpinners = new ArrayList<>(pawnsFromEntrance.size()); 458  for (PawnColour pawnColour : diningRoomCount.keySet()) { 459  //if diningRoom contains at least one pawn of that colour then create a JSpinner 460  if (diningRoomCount.get(pawnColour) > 0) { 461  optionPanel.add(new JLabel(pawnColour.toString())); 462  //create a new JSPinner that allows 0 as minimum, and as maximum the minimum between the number of pawns selected from entrance 463  // and the number of pawns of that color present in the diningroom 464  jSpinners.add(new JSpinner(new SpinnerNumberModel(0, 0, Math.min(pawnsFromEntrance.size(), diningRoomCount.get(pawnColour)), 1))); 465  //set JSpinnerName (useful to create pairs) 466  jSpinners.get(jSpinners.size() - 1).setName(pawnColour.toString()); 467  //add Jspinner to JoptionPane's panel 468  optionPanel.add(jSpinners.get(jSpinners.size() - 1)); 469  } 470  } 471  //create and show JOptionPane 472  result = JOptionPane.showConfirmDialog(this, optionPanel, 473  "Select pawns from diningRoom", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); 474  if (result == -1 || result == 2) return; 475  //create list of pairs 476  ArrayList<Pair<PawnColour, PawnColour>> pairs = new ArrayList<>(pawnsFromEntrance.size()); 477  OuterLoop: 478  for (JSpinner jSpinner : jSpinners) { 479  for (int i = 0; i < (Integer) jSpinner.getValue(); i++) { 480  //for every jSpinner create a new pair with firs element from entrance and the second one from diningRoom 481  pairs.add(new Pair<>(pawnsFromEntrance.get(pairs.size()), PawnColour.getPawnColourFromText(jSpinner.getName()))); 482  if (pairs.size() == 2) break OuterLoop; 483  } 484  } 485  //create playCharacterCard action and its playerActionRequest 486  playCharacterCard = new PlayCharacterCard(model.getMutableTurnOrder().getMutableCurrentPlayer().getId(), 487  cardPositionInGame, OptionalValue.empty(), OptionalValue.empty(), OptionalValue.of(pairs)); 488  playerActionRequest = new PlayerActionRequest(playCharacterCard); 489  } 490  } 491  //save action inside guiReader's history 492  guiSocketListener.savePlayerActionRequest(playCharacterCard); 493  //send playerActionRequest to Server 494  try { 495  socketWrapper.sendMessage(playerActionRequest); 496  } catch (IOException ex) { 497  throw new RuntimeException(ex); 498  } 499  } 500  501  502 }