0

Here is my code:

public class GUI
{
    JFrame frame;
    JPanel squares[][];

    public void movePiece(int oriX, int oriY, int destX, int destY)
    {
        squares[destY][destX] = squares[oriY][oriX];
        squares[oriY][oriX] = null;
        frame.setVisible(true);

    }


    /* Constructor credited to stackoverflow user ranzy
        http://stackoverflow.com/questions/2535417/chess-board-in-java */
    public GUI()
    {
        frame = new JFrame("Chess");
        squares = new JPanel[8][8];
        frame.setSize(500, 500);
        frame.setLayout(new GridLayout(8, 8));

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                squares[i][j] = new JPanel();

                if ((i + j) % 2 == 0) {
                    squares[i][j].setBackground(Color.white);
                } else {
                    squares[i][j].setBackground(Color.orange);
                }
                frame.add(squares[i][j]);
            }
        }

        ImageIcon pawnW = new ImageIcon(getClass().getResource("pawnW.png"));
        ImageIcon knightW = new ImageIcon(getClass().getResource("knightW.png"));
        ImageIcon bishopW = new ImageIcon(getClass().getResource("bishopW.png"));
        ImageIcon rookW = new ImageIcon(getClass().getResource("rookW.png"));
        ImageIcon queenW = new ImageIcon(getClass().getResource("queenW.png"));
        ImageIcon kingW = new ImageIcon(getClass().getResource("kingW.png"));

        ImageIcon pawnB = new ImageIcon(getClass().getResource("pawnB.png"));
        ImageIcon knightB = new ImageIcon(getClass().getResource("knightB.png"));
        ImageIcon bishopB = new ImageIcon(getClass().getResource("bishopB.png"));
        ImageIcon rookB = new ImageIcon(getClass().getResource("rookB.png"));
        ImageIcon queenB = new ImageIcon(getClass().getResource("queenB.png"));
        ImageIcon kingB = new ImageIcon(getClass().getResource("kingB.png"));



        squares[0][0].add(new JLabel(rookB));
        squares[0][1].add(new JLabel(knightB));
        squares[0][2].add(new JLabel(bishopB));
        squares[0][3].add(new JLabel(queenB));
        squares[0][4].add(new JLabel(kingB));
        squares[0][5].add(new JLabel(bishopB));
        squares[0][6].add(new JLabel(knightB));
        squares[0][7].add(new JLabel(rookB));

        squares[7][0].add(new JLabel(rookW));
        squares[7][1].add(new JLabel(knightW));
        squares[7][2].add(new JLabel(bishopW));
        squares[7][3].add(new JLabel(queenW));
        squares[7][4].add(new JLabel(kingW));
        squares[7][5].add(new JLabel(bishopW));
        squares[7][6].add(new JLabel(knightW));
        squares[7][7].add(new JLabel(rookW));

        for (int i = 0; i < 8; i++)
        {
            squares[1][i].add(new JLabel(pawnB));
            squares[6][i].add(new JLabel(pawnW));
        }

        frame.setVisible(true);
    }

}

When a user moves a piece, I want the squares to be updated. I.e. destination square should now hold the origin squares jlabel. I have attempted to do that with my movePiece method. But, this isn't creating the change I'm looking for. Am I required to use add/remove methods? Also - will it be necessary to call frame.setVisible(true) any time I make an update to the board?

Cameron Skinner
  • 51,692
  • 2
  • 65
  • 86
Collin
  • 1,777
  • 4
  • 26
  • 42
  • I don't see any code above that has anything to do with what your goal is. Where is the code where you try to move the pieces? You know of course that your program will only do what you tell it to do, no more and no less. Simply setting JLabels on the board in no way gives the program the magic ability to let the user move the labels. You would need a MouseListener and MouseMotionListener most likely, right? – Hovercraft Full Of Eels Feb 12 '14 at 21:00
  • in the movePiece function. – Collin Feb 12 '14 at 21:01
  • But movePiece by itself does nothing. What calls this method? How is it going to do anything if never called? – Hovercraft Full Of Eels Feb 12 '14 at 21:01
  • I have a game loop that calls it – Collin Feb 12 '14 at 21:02
  • 1
    You do? I don't see this anywhere. You either have to add/remove JLabels or put JLabels everywhere and add/remove their icons. – Hovercraft Full Of Eels Feb 12 '14 at 21:03
  • 1
    You don't want to set the squares reference to null, this is a reference to the JPanel, not the label. You need some way to know where the labels are and simply add them to there new parent, because of the way Swing works, this will automatically remove them from there current parent container – MadProgrammer Feb 12 '14 at 21:06
  • 1
    @MadProgrammer Great. Am I required to call frame.setVisible() after making the change? Anything to tell the gui to update? Or will doing the `.add` take care of this? – Collin Feb 12 '14 at 21:11
  • 1
    No, you don't need call setVisible again, add will invalidate the container automatically – MadProgrammer Feb 12 '14 at 21:17

2 Answers2

3

You can use Drag-and-Drop for this, or you can use a Mouselistener and MouseMotionListener. One example of the latter can be seen in my code here:

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import javax.swing.*;

public class Chess2 {
   private static void createAndShowUI() {
      JFrame frame = new JFrame("Chess 2");
      frame.getContentPane().add(new Chess2Gui().getMainComponent());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}

class Chess2Gui {
   private static final int RANKS = 8;
   private static final int FILES = 8;
   private static final Color DARK_COLOR = new Color(0, 100, 0);
   private static final Color LIGHT_COLOR = new Color(200, 200, 200);
   private static final Color DARK_PIECE_COLOR = Color.black;
   private static final int SQR_WIDTH = 80;
   private static final int PIECE_WIDTH = 60;
   private static final Dimension SQR_SIZE = new Dimension(SQR_WIDTH, SQR_WIDTH);

   private JLayeredPane mainLayeredPane = new JLayeredPane();
   private JPanel board = new JPanel(new GridLayout(RANKS, FILES));
   private JPanelSquare[][] jPanelSquareGrid = new JPanelSquare[RANKS][FILES];

   public Chess2Gui() {
      for (int rank = 0; rank < RANKS; rank++) {
         for (int file = 0; file < FILES; file++) {
            Color bkgd = DARK_COLOR;
            if (rank % 2 == file % 2) {
               bkgd = LIGHT_COLOR;
            }
            jPanelSquareGrid[rank][file] = new JPanelSquare(rank, file, bkgd);
            jPanelSquareGrid[rank][file].setPreferredSize(SQR_SIZE);
            board.add(jPanelSquareGrid[rank][file]);
         }
      }
      board.setSize(board.getPreferredSize());
      board.setLocation(0, 0);
      mainLayeredPane.add(board, JLayeredPane.DEFAULT_LAYER);
      mainLayeredPane.setPreferredSize(board.getPreferredSize());

      ImageIcon icon = new ImageIcon(ImageUtils2.createImage(PIECE_WIDTH, DARK_PIECE_COLOR));
      JLabel chessPiece = new JLabel(icon, SwingConstants.CENTER);

      jPanelSquareGrid[1][3].add(chessPiece);

      MyMouseAdapter mouseAdapter = new MyMouseAdapter();
      mainLayeredPane.addMouseListener(mouseAdapter);
      mainLayeredPane.addMouseMotionListener(mouseAdapter);

   }

   public JComponent getMainComponent() {
      return mainLayeredPane;
   }

   private class MyMouseAdapter extends MouseAdapter {
      private JLabel piece = null;
      private Point delta = null;
      private int oldRank = -1;
      private int oldFile = -1;

      @Override
      public void mousePressed(MouseEvent e) {
         Point p = e.getPoint();
         Component c = board.getComponentAt(p);
         for (int rank = 0; rank < jPanelSquareGrid.length; rank++) {
            for (int file = 0; file < jPanelSquareGrid[rank].length; file++) {
               if (jPanelSquareGrid[rank][file] == c) {
                  if (jPanelSquareGrid[rank][file].getChessPiece() != null) {

                     // the jPanelSquares are derived from JPanel but have a
                     // few of their own methods
                     piece = jPanelSquareGrid[rank][file].getChessPiece();
                     jPanelSquareGrid[rank][file].remove(piece);
                     oldRank = rank;
                     oldFile = file;
                     mainLayeredPane.add(piece, JLayeredPane.DRAG_LAYER);
                     int x = p.x - PIECE_WIDTH / 2;
                     int y = p.y - PIECE_WIDTH / 2;
                     piece.setLocation(x, y);

                     delta = new Point(p.x - x, p.y - y);
                     board.revalidate();
                     mainLayeredPane.repaint();
                     return;
                  }
               }
            }
         }

         oldFile = -1;
         oldRank = -1;
      }

      @Override
      public void mouseDragged(MouseEvent e) {
         if (piece != null) {
            Point p = e.getPoint();
            int x = p.x - delta.x;
            int y = p.y - delta.y;
            piece.setLocation(x, y);
            mainLayeredPane.revalidate();
            mainLayeredPane.repaint();
         }
      }

      @Override
      public void mouseReleased(MouseEvent e) {
         if (piece != null) {
            JPanelSquare sqr = (JPanelSquare) board.getComponentAt(e.getPoint());
            mainLayeredPane.remove(piece);
            if (sqr == null || !validMove(sqr)) {
               jPanelSquareGrid[oldRank][oldFile].add(piece);
            } else {
               sqr.add(piece);
            }

            piece = null;
            delta = null;

            oldRank = -1;
            oldFile = -1;

            board.revalidate();
            mainLayeredPane.repaint();
         }
      }

      // just a pawn's moves
      private boolean validMove(JPanelSquare sqr) {
         int rank = sqr.getRank();
         int file = sqr.getFile();

         if (file != oldFile) {
            return false;
         }
         if (oldRank == 1 && (rank != 2 && rank != 3)) {
            return false;
         }
         if (oldRank != 1 && rank != oldRank + 1) {
            return false;
         }
         return true;
      }
   }
}

@SuppressWarnings("serial")
class JPanelSquare extends JPanel {
   private int rank;
   private int file;
   private JLabel chessPiece = null;

   public JPanelSquare(int rank, int file, Color bkgrnd) {
      this.rank = rank;
      this.file = file;
      setBackground(bkgrnd);
      setLayout(new GridBagLayout());
   }

   public int getRank() {
      return rank;
   }

   public int getFile() {
      return file;
   }

   @Override
   public Component add(Component c) {
      chessPiece = (JLabel) c;
      return super.add(c);
   }

   @Override
   public void remove(Component comp) {
      chessPiece = null;
      super.remove(comp);
   }

   public JLabel getChessPiece() {
      return chessPiece;
   }
}

class ImageUtils2 {

   public static BufferedImage createImage(int size, Color color) {
      BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = img.createGraphics();
      g2.setColor(color);
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      g2.fillOval(size / 3, 0, size / 3, size / 3);
      g2.fillOval(size / 4, size / 4, size / 2, 2 * size / 3);
      g2.fillOval(size / 6, 2 * size / 3, 2 * size / 3, size / 2);
      g2.dispose();
      return img;
   }

}

This uses a JLayeredPane and when the user selects a piece, it (a JLabel) gets removed from board JPanel and raised to the JLayeredPane's DRAG_LAYER, until it is released over a valid position.

Note, this code was taken from my previous answer here. For more details on the code, please check out that answer.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
2

How about the JFrame remove(); method? Use it like this:

frame.remove(JLabelName);
BitNinja
  • 1,477
  • 1
  • 19
  • 25