0

I am trying to implement Tetris in Swing, for that I am trying to draw rectangles adjacent to each, but the second rectangle is not coming adjacent to the first.

Also if getPreferredSize() returns anything less than 50,50 then nothing shows up in the screen. What is wrong in this code and how to paint adjacent rectangles.

public class Tetris extends JFrame
{

    public Tetris(String string)
    {
        super(string);
    }
    public static void main(String[] args)
    {
        Tetris tetris = new Tetris("Tetris");
        tetris.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel mainPanel = new JPanel();
        tetris.getContentPane().add(mainPanel);
        tetris.setVisible(true);
        tetris.setLocationRelativeTo(null);
        tetris.pack();
        tetris.setSize(500, 500);
        tetris.setResizable(false);
        tetris.paintBoard(mainPanel);
    }

    public void paintBoard(JPanel mainPanel)
    {
        Piece p1 = new Piece(10,10,50,50,Color.GREEN);
        Piece p2 = new Piece(60,10,50,50,Color.RED);
        mainPanel.add(p1);
        mainPanel.add(p2);
    }
}

public class Piece extends JComponent
{
    private int X = 0;
    private int Y = 0;
    private int H = 0;
    private int W = 0;
    private Color c;

    public Piece(int X, int Y, int W, int H, Color c)
    {
        this.X = X;
        this.Y = Y;
        this.W = W;
        this.H = H;
        this.c = c;
    }

    @Override
    public void paintComponent(Graphics g)
    {
        g.setColor(c);
        g.drawRect(X, Y, W, H);
        g.fillRect(X, Y, W, H);
        System.out.println("g.drawRect("+X+", "+Y+", "+W+", "+H+")");
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(50, 50);
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
Mahendran
  • 2,191
  • 5
  • 24
  • 40

5 Answers5

2

if getPreferredSize() returns anything less than 50,50 then nothing shows up in the screen

This is because you have set a X co-ordinate of 60 for the "red" Piece but the preferred size width of the component is 50 so the component is drawn off screen.

To add components you could simply draw all Piece components at 0, 0 and let the layout manager take care of the positioning. Aside from that, given that this is a game of Tetris, you should consider painting all components on a single component and use a Swing Timer to manipulate the pieces.

Reimeus
  • 158,255
  • 15
  • 216
  • 276
1
  • override getPreferredSize for JPanel, otherwise JPanel returns zero Dimension

  • put all Objects to the array

  • inside paintComponent loop only in array

  • use Swing Timer (only one instance) for animations

  • example about all a.m. points

Community
  • 1
  • 1
mKorbel
  • 109,525
  • 20
  • 134
  • 319
1

The overall problem is a Swing Layout issue. Your mainPanel JPanel has a default layout, FlowLayout, that attempts to arrange each thing (Piece) that you add to it. Each Piece's paintComponent will only control painting itself, not on the overall mainPanel. So your Pieces are not being painted relative to the overall mainPanel.

Something Like:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Tetris extends JFrame
{

    public Tetris(String string)
    {
        super(string);
    }
    public static void main(String[] args)
    {
        Tetris tetris = new Tetris("Tetris");
        tetris.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel mainPanel = new JPanel();
        mainPanel.setLayout(new BorderLayout());
        tetris.getContentPane().setLayout(new BorderLayout());
        tetris.getContentPane().add(mainPanel, BorderLayout.CENTER);
        tetris.setLocationRelativeTo(null);
        tetris.pack();
        tetris.setSize(500, 500);
        tetris.setResizable(false);
        tetris.setVisible(true);
        tetris.paintBoard(mainPanel);
    }

    public void paintBoard(JPanel mainPanel)
    {
        Piece p1 = new Piece(10,10,50,50,Color.GREEN);
        Piece p2 = new Piece(60,10,50,50,Color.RED);

        Board board = new Board();

        board.addPiece(p1);
        board.addPiece(p2);

        mainPanel.add(board, BorderLayout.CENTER);
    }

    private class Board extends JComponent
    {
        private List<Piece> pieces = new ArrayList<Piece>();

        public void addPiece(Piece piece)
        {
            pieces.add(piece);
        }

        @Override
        public void paintComponent(Graphics g)
        {
            for(Piece piece : pieces)
            {
                g.setColor(piece.c);
                g.drawRect(piece.X, piece.Y, piece.W, piece.H);
                g.fillRect(piece.X, piece.Y, piece.W, piece.H);
            }
        }
    }

    private class Piece
    {
        private int X = 0;
        private int Y = 0;
        private int H = 0;
        private int W = 0;
        private Color c;

        public Piece(int X, int Y, int W, int H, Color c)
        {
            this.X = X;
            this.Y = Y;
            this.W = W;
            this.H = H;
            this.c = c;
        }   
    }
}
SeKa
  • 1,825
  • 12
  • 7
1

There is one logical error here. You are painting Piece using paintComponent() method, but the starting x and y coordinates you are giving is prabably in context of mainPanel (10, 10 or 60, 10) while you need to give them in context of current component Piece, for example try this:

 @Override
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    g.setColor(c);
    g.drawRect(0, 0, W, H);
    g.fillRect(0, 0, W, H);
    System.out.println("g.drawRect("+X+", "+Y+", "+W+", "+H+")");
}

it shows properly what you want.

It also explains why the smaller size was not working, thing in the context of current component not parent component.

vishal_aim
  • 7,636
  • 1
  • 20
  • 23
0

You need to set the LayoutManager of JPanel to null if you want the Pieces that you add to show up on the coordinates that you specify.

public void paintBoard(JPanel mainPanel)
{
    Piece p1 = new Piece(10,10,50,50,Color.GREEN);
    Piece p2 = new Piece(60,10,50,50,Color.RED);
    mainPanel.setLayout(null)
    mainPanel.add(p1);
    mainPanel.add(p2);
}
Rakhitha
  • 328
  • 2
  • 11