views:

406

answers:

3

(second question in a few hours)

Kay so I'm making a chess variant in java, I have my console program working how I want it but now I'm trying to convert it to a swing GUI while STILL keeping the console things intact. So up to now I have my array of squares with pieces in them for the console, and a 2-dimensional array of JPanels with pieces in them for the GUI. I haven't implemented moving pieces in the GUI yet so I'm still doing it from the console but the actual GUI doesn't update after I've moved a piece...even though it does on the console (sorry if this is confusing).

The GUI consists of a constructor which calls some methods drawBoard() and drawSidebar() and sets sizes, titles etcetc...so this is what the main method looks like:

public static void main(String args[]) {
 ChessGUI GUI = new ChessGUI();
 Board console = new Board();
 do {
  console.printBoard();
  console.getScore();
  console.getMove();
  GUI.boardPanel.revalidate();
  GUI.sidePanel.revalidate();
  GUI.repaint();
 } while (true);
}

and drawBoard() incase it makes any difference:

public void drawBoard() {
 LayoutManager layout = new GridLayout(NUMBER_OF_ROWS, NUMBER_OF_COLS);
 boardPanel.setLayout(layout);
 boardPanel.setPreferredSize(new Dimension(200, 450));
 chessBoard = new JPanel[NUMBER_OF_ROWS][NUMBER_OF_COLS];
 for (int i = 0; i < NUMBER_OF_ROWS; i++) {
  for (int j = 0; j < NUMBER_OF_COLS; j++) {
   chessBoard[i][j] = new JPanel();
   chessBoard[i][j].setBackground(getColor(i,j));
   int index = i * 4 + j;
   if (!(boardArray.chessBoard[index].square.isEmpty())) {
    Piece piece = (Piece) boardArray.chessBoard[index].square.firstElement();
    chessBoard[i][j].add(new JLabel(piece.toString()));
   }
   boardPanel.add(chessBoard[i][j]);
  }
 }
}

the repaint and revalidate methods don't seem to be calling at all, even though the console is being updated :(

+1  A: 

It looks like you're never actually removing anything from 'boardPanel,' even though you are resetting its LayoutManager.

A safer approach might be to remove 'boardPanel' from its container, then create a new instance for 'boardPanel,' add that to the container, then add the other JPanel pieces to this new 'boardPanel.' Effectively, you would be reconstructing the entire JPanel hierarchy after every move.

As you've noticed, Swing can be quite finicky once you start trying to add/move/remove components after they've been added to containers. For games, often the best approach would be to have 1 JComponent/Component and use Java2D methods to draw on top of it. Swing is typically only used for forms-based applications.

Outlaw Programmer
+2  A: 

Changing the layout doesn't do anything.

You need to call boardPanel.removeChildren()

However, this is going to be extremely slow.

Really, what you should be doing is have your own JPanel, overwrite paintComponent() and draw the images into the appropriate dimensions using Java Graphics.

Milan Ramaiya
+1  A: 

I don't really understand what you are doing. But it doesn't make sense to recreate the entire board panel every time a move is made. All Swing components can only have a single parent, to the easier solution is to just move the piece from one panel to the other. So the code would be something like:

previousPanel.remove( piece );
currentPanel.add( piece );
previousPanel.revalidate();
previousPanel.repaint();
currentPanel.revalidate();
camickr