如何在Swing中绘制相邻的矩形?

时间:2013-03-12 10:55:41

标签: java swing jpanel paintcomponent

我正在尝试在Swing中实现俄罗斯方块,因为我试图绘制与每个相邻的矩形,但第二个矩形不会与第一个相邻。

此外,如果getPreferredSize()返回小于50,50的任何内容,则屏幕上不会显示任何内容。 这段代码有什么问题以及如何绘制相邻的矩形。

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);
    }
}

5 个答案:

答案 0 :(得分:2)

  

如果getPreferredSize()返回小于50,50的任何内容,则屏幕上不会显示任何内容

这是因为你为" red"设置了一个60的X坐标。 Piece但组件的首选大小宽度为50,因此组件将在屏幕外绘制。

要添加组件,您只需在Piece处绘制所有0, 0个组件,然后让布局管理器负责定位。除此之外,鉴于这是一个俄罗斯方块游戏,你应该考虑在一个组件上绘制所有组件,并使用Swing Timer来操作这些组件。

答案 1 :(得分:1)

  • 覆盖getPreferredSize的{​​{1}},否则JPanel返回零JPanel

  • 将所有Dimension放入数组

  • 仅在数组

    中的Objects循环内
  • 使用paintComponent(只有一个实例)进行动画

  • example about all a.m. points

答案 2 :(得分:1)

整体问题是Swing Layout问题。您的mainPanel JPanel有一个默认布局FlowLayout,它尝试排列您添加到它的每个东西(Piece)。每个Piece的paintComponent只控制绘画本身,​​而不是整个主面板。因此,您的Pieces不会相对于整个mainPanel进行绘制。

喜欢的东西:

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;
        }   
    }
}

答案 3 :(得分:1)

这里有一个逻辑错误。您正在使用Piece方法绘制paintComponent(),但您提供的起始x和y坐标是mainPanel(10,10或60,10)的上下文,而您需要提供它们在当前组件Piece的上下文中,例如试试这个:

 @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+")");
}

它正确显示了你想要的东西。

它还解释了为什么较小的尺寸不起作用,当前组件的上下文中的东西不是父组件。

答案 4 :(得分:0)

如果您希望添加的碎片显示在您指定的坐标上,则需要将JPanel的LayoutManager设置为null。

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);
}