/**
  * Callback from the Grid objects, for when the button gets pressed. This is really an example of
  * cyclic dependency, but, we'd need to use some more object-oriented features to do a good job
  * fixing it.
  *
  * @param grid Grid object that was clicked on.
  * @param row row of the grid that was clicked
  * @param column column of the grid that was clicked
  */
 public void gridPress(Grid grid, int row, int column) {
   if (grid == humanGrid) {
     game.selectHumanGridSquare(row, column);
   } else {
     game.selectComputerGridSquare(row, column);
   }
   updateStatus();
   repaint();
 }
 /**
  * Callback used to respond to button presses.
  *
  * @param e event capturing information about the button press.
  */
 public void actionPerformed(ActionEvent e) {
   if (e.getSource() == hButton) {
     game.setHorizontal(true);
   }
   if (e.getSource() == vButton) {
     game.setHorizontal(false);
   }
   updateStatus();
 }
  /** Update the status of the GUI based on any changes in the game object. */
  private void updateStatus() {
    if (game.donePlacingShips()) {
      // Kill the ship highlight and disable the vertical/horizontal buttons.
      humanGrid.setHoverShape(null);
      hButton.setEnabled(false);
      vButton.setEnabled(false);
    } else {
      int len = game.placingLength();
      boolean horiz = game.placingHorizontal();
      humanGrid.setHoverShape(new Dimension(horiz ? len : 1, horiz ? 1 : len));
    }

    message.setText(game.getStatus());
    repaint();
  }
  /**
   * Make a GUI for the battleship game.
   *
   * @param game Game object that keeps up with the current state of the game.
   */
  public BattleshipGUI(Battleship game) {
    this.game = game;

    this.game = game;
    // Ships are visible on the human grid but not on the computer grid
    // (last argument)
    humanGrid = new Grid(game.getHumanBoard(), this, true);
    computerGrid = new Grid(game.getComputerBoard(), this, false);
    setTitle("Battleship Game");
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setLayout(new BorderLayout());

    // Add a message field centered below the game
    Box gamePanel = new Box(BoxLayout.X_AXIS);
    add(gamePanel, BorderLayout.CENTER);
    message = new JLabel("Game begins", JLabel.CENTER);
    message.setFont(DEFAULT_FONT);
    add(message, BorderLayout.SOUTH);

    // Add human and computer panels to the game; the human panel has a
    // title, grid, and buttons; the computer panel has only a title and a
    // grid
    JPanel human = new JPanel();
    human.setLayout(new BoxLayout(human, BoxLayout.Y_AXIS));
    JPanel computer = new JPanel();
    computer.setLayout(new BoxLayout(computer, BoxLayout.Y_AXIS));
    human.setAlignmentY(Component.TOP_ALIGNMENT);
    gamePanel.add(human);
    gamePanel.add(Box.createRigidArea(new Dimension(5, 0)));
    computer.setAlignmentY(Component.TOP_ALIGNMENT);
    gamePanel.add(computer);

    // Add three parts to the human panel
    JLabel humanLabel = new JLabel("Human", JLabel.CENTER);
    humanLabel.setFont(DEFAULT_FONT);
    JPanel buttonPanel = new JPanel();
    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
    human.add(humanLabel);
    human.add(humanGrid);
    human.add(buttonPanel);

    // Set up the buttons
    hButton = new JButton("Horizontal");
    hButton.setFont(DEFAULT_FONT);
    hButton.addActionListener(this);
    vButton = new JButton("Vertical");
    vButton.setFont(DEFAULT_FONT);
    vButton.addActionListener(this);
    buttonPanel.add(hButton);
    buttonPanel.add(vButton);

    // Add two parts to the computer panel
    JLabel computerLabel = new JLabel("Computer", JLabel.CENTER);
    computerLabel.setFont(DEFAULT_FONT);
    computer.add(computerLabel);
    computer.add(computerGrid);

    updateStatus();

    pack();
    setVisible(true);
  }