0

I'm making a chess game, and I'm using a chessboard that I made with paint at 480x480, and got the pieces from some sprite and made each one of them 60x60 and transparent background. I managed to put the chessboard and the pieces on screen, but the positions are messy. I'm using null layout. I did:

chessBoardLabel.setBounds(0, 0+25, 480, 480);

the +25 is because of the Frame's thing that is on top and looks like it is considered in positioning. as for the piece, for example:

for (int i = 0; i <= 7; i++)
 whitePawnArray[i] = new whitePawnPiece(i*60,420+25); 

the parameters set the xPos and yPos. For the bounds function, I did:

whitePawnLabel.setBounds(this.xPos, this.yPos, this.xPos+60, this.yPos+60);

But this happens: http://i.imgur.com/MF9Njbi.jpg

If I do that:

for (int i = 0; i <= 7; i++)
whitePawnArray[i] = new whitePawnPiece(i*40,280+15);

this happens: http://i.imgur.com/Pm1fMSp.jpg

First: what happened to the positioning? Why doesn't it follow what I intended it to be? Second: what is the 8th piece doing in the middle of nowhere?

package chess.game;
import java.util.*;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class chessMain extends JFrame{
    public static void main (String arguments[]){

    //Create White
    whitePiece white_piece = new whitePiece();

    whitePawnPiece[] whitePawnArray = new whitePawnPiece[8];
    for (int i = 0; i <= 7; i++) whitePawnArray[i] = new whitePawnPiece(i*40,280+15);

    /*whiteTowerPiece[] whiteTowerArray = new whiteTowerPiece[2];
    whiteTowerArray[0] = new whiteTowerPiece(0,420);
    whiteTowerArray[1] = new whiteTowerPiece(420,420);

    whiteHorsePiece[] whiteHorseArray = new whiteHorsePiece[2];
    whiteBishopPiece[] whiteBishopArray = new whiteBishopPiece[2];
    whiteKingPiece whiteKing = new whiteKingPiece();
    whiteQueenPiece whiteQueen = new whiteQueenPiece();*/

    //Create Black

    JFrame frame = new JFrame();
    JPanel panel;

    //Initialize
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setTitle("Chess");
    frame.setSize (640,640);
    frame.setResizable(false);
    frame.setLayout(null);
    panel = new JPanel();
    panel.setLayout(null);
    frame.getContentPane().add(panel);

    //draw chessBoard
    ImageIcon chessBoardIcon = new           ImageIcon(frame.getClass().getResource("/chess/art/Chess_Art/chessBoard.png"));
    JLabel chessBoardLabel = new JLabel(chessBoardIcon);
    panel.add(chessBoardLabel);
    chessBoardLabel.setBounds(0, 0+25, 480, 480);
    frame.setComponentZOrder(chessBoardLabel, 1);
    frame.setComponentZOrder(panel, 2);
    //draw Pawn
    for (int i = 0; i<=7; i++){
        panel.add(whitePawnArray[i].whitePawnLabel);
        whitePawnArray[i].draw();
        frame.setComponentZOrder(whitePawnArray[i].whitePawnLabel, 0);
    }

    frame.setVisible(true);

}
}

public class whitePawnPiece extends whitePiece{
    JLabel whitePawnLabel;
    ImageIcon whitePawnIcon;
    public whitePawnPiece(int x, int y){
        whitePawnIcon = new ImageIcon(getClass().getResource("/chess/art/Chess_Art/white/whitePawnPiece.png"));
        whitePawnLabel = new JLabel (whitePawnIcon);
        //whitePawnLabel.setOpaque(true);
        this.xPos = x;
        this.yPos = y;
        //this.draw();
    }

    @Override
    public void move(int newX, int newY){
        this.xPos = (newX/60)*60;                     //calcular nova pos
        this.yPos = (newY/60)*60;
        this.draw();
    }
    /*public void possibleMoves(){
        selectorMark.drawNew(this.xPos, this.yPos);
        selectorMark.drawNew(this.xPos - 60, this.yPos - 60);
        if (this.yPos == 420)  selectorMark.drawNew(this.xPos - 120, this.yPos - 120);
    }*/

    @Override
    public void draw(){
        //whitePawnIcon.paintIcon(null, chessGUI2.getGraphics(), xPos, xPos);
        whitePawnLabel.setBounds(this.xPos, this.yPos, this.xPos+60, this.yPos+60);     //x, y, width, height
    }

}

public class whitePiece{
    int xPos, yPos;

    public void move(){}
    public void draw(){}

}

First time putting whole code hope I edited it right hehe

WalrusNine
  • 103
  • 9
  • 1
    Well, that's why it's highly recommended to use [`LayoutManagers`](http://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html)instead of absolute positioning. – Azad Mar 14 '14 at 23:06
  • Maybe you should consider using a single component and paint in it (override [`paintComponent()`](http://docs.oracle.com/javase/7/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics))) – xav Mar 14 '14 at 23:08
  • @Azad but when I was using the NetBeans IDE to make the GUI, I couldn't overlay the images, except when using null/absolute layout. Is there any Layout that doesn't complicate my life and let me put 2 images in the same position and use something like setComponentZOrder? – WalrusNine Mar 14 '14 at 23:10
  • @xav but then moving the pieces would be a nightmare wouldn't it? – WalrusNine Mar 14 '14 at 23:11
  • @WalrusNine: Yes, `CardLayout` will do that for you ;) – Azad Mar 14 '14 at 23:11
  • @WalrusNine: nope, just handle each piece as a business object that provides a `paint(Graphics2D)` method to be painted in your component. Using a `CardLayout` or a single component may depends on how user interacts with pieces (e.g. mouse clicks) – xav Mar 14 '14 at 23:13
  • I would just use a `GridLayout` filled with `JPanel`s and then `paintComponent()` the pieces on. Or put `JLabel`s with icons that relate to the pieces into the `JPanel`s. – Rudi Kershaw Mar 14 '14 at 23:15
  • Funny. I just did the same type of thing last month. I just repaint the whole thing on a JPanel, everything (board and pieces) during each screen refresh. I didn't bother with any layout managers on the game panel at all. – MarsAtomic Mar 14 '14 at 23:18
  • @Azad I didn't understand very well the CardLayout...in the java docs it says "Only one card is visible at a time", how can I make the chessboard, the pieces, and, that I still have to implement, the markers for possible moves for that piece when having this limitation? – WalrusNine Mar 14 '14 at 23:20
  • @xav hmm I'm still trying to avoid using this paintComponent, Graphics related things as I just recently started using GUI and this part confuses me. Intended to use it as last resort... – WalrusNine Mar 14 '14 at 23:21
  • *"the +25 is because of the Frame's thing that is on top and looks like it is considered in positioning. as for the piece, for example"* - That's because you've overriden `paint` of the `JFrame` - this is one (of many) reasons why you should never override `paint` of top level containers. Change the border to a `JPanel` and override it's `paintComponent` method instead – MadProgrammer Mar 14 '14 at 23:29
  • The position of a component is relative to the parent. Adding components to the content pane of the frame places them within the viewable area of the frame (within the frame decorations). This means that any calculation you make is within the wrong context (0x0) will be the top left corner of the content pane, not the frame. Take a look at [this](http://stackoverflow.com/questions/13734069/how-can-i-set-in-the-midst/13734319#13734319) and [this](http://stackoverflow.com/questions/13457237/how-to-get-the-exact-middle-of-a-screen-even-when-re-sized/13460914#13460914) for more details – MadProgrammer Mar 14 '14 at 23:34
  • And [this](http://stackoverflow.com/questions/16473627/java-jframe-setsizex-y-not-working/16473639#16473639) just because... – MadProgrammer Mar 14 '14 at 23:34
  • See [Making a robust, resizable Chess GUI](http://stackoverflow.com/q/21142686/418556). It uses buttons for the places on the chess board. A button accepts an icon to represent the chess piece, and provides ways to interact with keyboard and mouse. The buttons are arranged using a `GridLayout`. – Andrew Thompson Mar 15 '14 at 00:47
  • @WalrusNine: Sorry about `CardLayout`, it was a misunderstanding, I thought you need two panels in the same location but only one of them be visible in a time. – Azad Mar 15 '14 at 20:26

1 Answers1

2
  • Don't use CardLayout for this.
  • I'd use a JPanel that uses GridLayout to hold an 8x8 grid of chess square JPanels.
  • I'd place that in a JLayeredPane.
  • I'd add my pieces to the appropriate chess square JPanel.
  • When moving a piece, I'd lift it up to the drag layer of the JLayeredPane.

Also:

  • Don't draw directly on to a top-level window such as a JFrame.
  • Don't override the paint method.
  • Instead, if you must do drawing, override the paintComponent(Graphics g) of a JPanel or JComponent.
  • But again, if you create your chess board out of small JPanel chess squares, it is easy and natural to place pieces on the chess square and have it placed well.

For example, please check out my code here.

Community
  • 1
  • 1
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • 1
    The OP is overriding `paint` of the frame, this is why they need the +25 offset...which will be destroyed the moment they change look and feels. Would mind mentioning proper painting process... – MadProgrammer Mar 14 '14 at 23:30
  • can I use a file with paintComponent or should I just stick with JLabel? – WalrusNine Mar 14 '14 at 23:35
  • This is also why they are having issues with placement of there objects. The OP seems to have added the pieces to the content pane and is trying to use the positional context of the frame to place elements, which is going to push them of place (as the contextual space coordinates are wrong) - I have links in the comments you can borrow unless you have your own... – MadProgrammer Mar 14 '14 at 23:36
  • @WalrusNine This is why you should be providing a runnable example of your problems. Where making guesses at observations from experience... – MadProgrammer Mar 14 '14 at 23:36
  • @WalrusNine: Your Chess pieces can be JLabels that hold ImageIcons, and the Icons can be read from a file. Again, please look at my linked answer and code. – Hovercraft Full Of Eels Mar 14 '14 at 23:37
  • @MadProgrammer there you go hehe, the code is there. It only has whitePawnPiece for now... – WalrusNine Mar 14 '14 at 23:48
  • 1
    @WalrusNine Your code a convoluted mess of circular references...why does `whitePiece` extend from `chessMain` which is your main frame???? – MadProgrammer Mar 15 '14 at 00:09
  • @MadProgram oh lol, ty :D started learning java last month, but I'm being more worried about assembly so sometimes this happens xD That's why I didn't want to show the code, had the feeling it would only worsen the situation hehe – WalrusNine Mar 15 '14 at 00:31
  • well just wanted to say that the GridLayout is working like a charm, I'm adjusting my pieces classes to this layout (and as the objective of this assignment is not to see if I know the java GUI-related features, but overriding and other minor ones, so if I may, I'm borrowing a little bit of your code :P) I just didn't understand very well the LayeredPane, what's that for? And another thing, I want to make lots of games using java from now on because I really like it hehe, and in about 6 months I intend to start making a mini-RPG game. Which layout would be the best? Just to have an idea... – WalrusNine Mar 15 '14 at 02:54
  • @WalrusNine: the JLayeredPane allows for you to place your components in a container and more easily control their z-order, their order of layering. So likely the JPanel that holds the chess square grid will be placed in the JLayeredPane's bottom-most layer, the `DEFAULT_LAYER`, while any JLabels that are being dragged by the user would go on a higher layer, the top layer in fact, the `DRAG_LAYER`. – Hovercraft Full Of Eels Mar 15 '14 at 11:54