1

I'm begining a little project to create a simple checkers game. However it's been a long time since I've used the java GUI tools. The goal of the code at this point is to draw the initial board (red pieces at top, black at bottom). However all I get when I run the code is a blank frame. I'm also a little uncertain if my circle drawing code will do what I want (ie create solid red or black circles inside certain squares) Here is the code. Thanks in advance for any help/suggestions

EDIT: I should probably alternate drawing blue and gray squares or else the thing will probably just be a giant blue blob, however I'll settle for a giant blue blob at this point :p

import javax.swing.*;
import java.awt.*;

public class CheckersServer 
{
    public static class Board
    {
        private JFrame frame = new JFrame();
        private JPanel backBoard = new JPanel();

    Board()
    {

        frame.setSize(905,905);
        backBoard.setSize(900,900);
        frame.setTitle("Checkers");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        backBoard.setVisible(true);


        boardSquare bs;
        String type = null;
        //Filling in Red Side
        for (int i = 0; i <=1; i++)
        {
            for(int j = 0; j < 9; j++)
            {
                if(j % 2 == 0)
                {
                    type = "Red";
                }
                else 
                {
                    type = "Blank";
                }

                bs = new boardSquare(100*j,100*i,type);
                backBoard.add(bs); 

            }

        }
        //Filling in empty middle
        type = "Blank";
        for (int i = 2; i < 7; i++)
        {
            for(int j = 0; j < 9; j++)
            {

                bs = new boardSquare(100*j,100*i,type);
                backBoard.add(bs); 

            }

        }

        //Filling in Black side
        for (int i = 7; i < 9; i++)
        {
            for(int j = 0; j < 9; j++)
            {
                if(j % 2 != 0)
                {
                    type = "Black";
                }
                else 
                {
                    type = "Blank";
                }

                bs = new boardSquare(100*j,100*i,type);
                backBoard.add(bs); 

            }

        }

        backBoard.repaint();
        frame.add(backBoard);
        frame.repaint();


    }

    private class boardSquare extends JComponent
    {
        private int x; //x position of the rectangle measured from top left corner
        private int y; //y position of the rectangle measured from top left corner

        private boolean isBlack = false;
        private boolean isRed = false;

        public boardSquare(int p, int q, String type)
        {
            x = p;
            y = q;
            if (type.equals("Black"))
            {
                isBlack = true;
                isRed = false;
            }
            else if (type.equals("Red"))
            {
                isRed = true;
                isBlack = false;
            }
            else if (type.equals("Blank"))
            {
                isBlack = false;
                isRed = false;
            }

        }
        public void paintComponent(Graphics g)
        {
            Graphics2D g2 = (Graphics2D) g;
            Rectangle box = new Rectangle(x,y,100,100);
            g2.draw(box);
            g2.setPaint(Color.BLUE);
            g2.fill(box);

            if(isBlack)
            {
                g2.fillOval(x, y,100 ,100 );
                g2.setColor(Color.black);
                g2.drawOval(x, y, 100, 100);
            }

            else if(isRed)
            {
                g2.fillOval(x, y,100 ,100 );
                g2.setColor(Color.red);
                g2.drawOval(x, y, 100, 100);
            }

        }
    }


}


public static void main(String[] args)
{
    Board game = new Board();

}
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211
Adam Sturge
  • 57
  • 2
  • 3
  • 14
  • Thanks for all the help! Yes I misunderstood what the coordinates x and y were measured relative to. Gridlayout seems to be a step in the right direction as well. – Adam Sturge Mar 06 '12 at 01:16
  • You could mark one of the responses as a correct answer. This encourages people to answer more of your questions in the future. And, it's good SO etiquette. Glad your program works now. – Tony Mar 06 '12 at 04:24
  • _do not_ follow the incorrect advice to setXXSize (with xx= preferred, min, max) - instead let the BoardSquare (node the name refactor to comply to java naming conventions :-) decide about its size by overriding its getters. – kleopatra Mar 06 '12 at 10:09

3 Answers3

3

You have several issues.

Java UI is layout-based, which means that when you add a component to a parent, the parent's layout determines where the child component will be placed. You don't have any code to set up the layout, and so your application is using the defaults (FlowLayout is the default, and this may work in your case, as long as your JFrame and children are the appropriate size).

The bigger problems are in your boardSquare class. By default, JPanels have a dimension of 10x10. You aren't specifying the size, and so all your squares are 10x10. You need to tell the squares how big they are. You can do this in the boardSquare constructor:

setPreferredSize(new Dimension(100, 100));

Finally, in your drawing code, you are doing an offset of x,y when drawing the squares and circles. This is an offset from the top-left corner of the component. Your components (after setting the size) will be 100x100 pixels. But if your x,y are greater than these values, you will be drawing outside of the bounds of the component. Instead, these values should be set to 0,0 because that is the top-left corner of the component you are drawing in.

By just setting the preferred size of the squares and setting x,y to 0, I was able to get the squares drawing in the frame, though it wasn't pretty. You will need to work on setting the correct layout before it will be laid out correctly.

Tony
  • 1,401
  • 9
  • 11
  • don't use setXXSize ever, for some reasons http://stackoverflow.com/questions/7229226/should-i-avoid-the-use-of-setpreferredmaximumminimumsize-methods-in-java-swi (to @Mike Clark as well) – kleopatra Mar 06 '12 at 10:10
1
import javax.swing.*;
import javax.swing.border.LineBorder;

import java.awt.*;

public class CheckersServer2 
{
    public static String type_BLANK = "BLANK";
    public static String type_RED = "RED";
    public static String type_BLACK = "BLACK";

    public static int width = 100;
    public static int height = 100;

    public static class Board
    {
        private JFrame frame = new JFrame();
        private JPanel backBoard = new JPanel();

    Board()
    {
        int numRows = 8;
        int numCols = 8;

        frame.setSize(905,905);
        backBoard.setSize(900,900);
        frame.setTitle("Checkers");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
        backBoard.setVisible(true);

        String type;
        for(int r=0; r<numRows; r++){
            for(int c=0; c<numCols; c++){
                //
                type = type_BLANK;
                if(c%2==0){
                    if(r==0 || r==2) {
                        type = type_RED;
                    }else if(r==6){
                        type = type_BLACK;
                    }
                }else{
                    if(r==1){
                        type = type_RED;
                    } else if(r==5 || r==7) {
                        type = type_BLACK;
                    }
                }
                backBoard.add(new BoardSquare(r,c,type));               
            }           
        }

        backBoard.repaint();
        frame.add(backBoard);
        frame.repaint();


    }

    private class BoardSquare extends JComponent
    {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private int x; //x position of the rectangle measured from top left corner
        private int y; //y position of the rectangle measured from top left corner

        private boolean isBlack = false;
        private boolean isRed = false;

        public BoardSquare(int p, int q, String type)
        {
            //this.setBorder(new LineBorder(Color.CYAN, 2));
            this.setPreferredSize(new Dimension(width, height));

            x = p;
            y = q;
            if (type.equals(type_BLACK))
            {
                isBlack = true;
                isRed = false;
            }
            else if (type.equals(type_RED))
            {
                isRed = true;
                isBlack = false;
            }
            else if (type.equals(type_BLANK))
            {
                isBlack = false;
                isRed = false;
            }

        }
        public void paintComponent(Graphics g)
        {
            Graphics2D g2 = (Graphics2D) g;
            Rectangle box = new Rectangle(x,y,width,height);
            g2.draw(box);
            g2.setPaint(Color.BLUE);
            g2.fill(box);
            int ovalWidth = width - 15;
            int ovalHeight = ovalWidth;
            if(isBlack)
            {
                g2.setColor(Color.black);
                g2.fillOval(x, y, ovalWidth, ovalHeight);
                g2.drawOval(x, y, ovalWidth, ovalHeight);
            }

            else if(isRed)
            {
                g2.setColor(Color.red);
                g2.fillOval(x, y, ovalWidth, ovalHeight);
                g2.drawOval(x, y, ovalWidth, ovalHeight);
            }

        }
    }


}


public static void main(String[] args)
{
    Board game = new Board();

}
}
UCan DoIt
  • 11
  • 1
1

Here are some hints:

  • Your BoardSquares have dimension 0x0. Not a good size for something you want to be visible to the user.

  • To help visualize what's going on, cause each BoardSquare to be 100x100 pixels in size, and give them a border. Now you can see where they are showing up in your GUI. Your GUI code still needs significant changes, but this will at least let you start seeing what you're dealing with.

        public BoardSquare(int p, int q, String type)
        {
            this.setBorder(new LineBorder(Color.CYAN, 2));
            this.setPreferredSize(new Dimension(100, 100));
    
            // ... etc ...
    
  • BoardSquare seems to be coded to draw its contents based on coordinates from the absolute topmost leftmost point in the window, but they should be coded to draw themselves from the topmost leftmost point of the BoardSquare itself. That is, components should only draw within their own boundaries, and they should use coordinates that assume 0,0 designates the top,left of the component, not of the window.

  • If you want to use BoardSquares (JComponents) and add them to the frame, you probably should use a different layout manager, like GridLayout. FlowLayout won't give you the kind of precise positioning you want.

Mike Clark
  • 10,027
  • 3
  • 40
  • 54