0

我正在尝试在 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);
    }
}
4

5 回答 5

2

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

这是因为您已将“红色”的 X 坐标设置为 60,Piece但组件的首选尺寸宽度为 50,因此组件被绘制到屏幕外。

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

于 2013-03-12T11:08:43.513 回答
1
  • 覆盖getPreferredSizefor JPanel,否则JPanel返回零Dimension

  • 把所有Objects的东西放到数组中

  • 内部paintComponent循环仅在数组中

  • 使用Swing Timer(仅一个实例)动画

  • 关于所有上午点的示例

于 2013-03-12T11:12:23.233 回答
1

总体问题是 Swing 布局问题。您的 mainPanel JPanel 有一个默认布局 FlowLayout,它会尝试排列您添加到其中的每个事物(片段)。每个 Piece 的 paintComponent 只会控制绘画本身,​​而不是在整个 mainPanel 上。因此,您的 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;
        }   
    }
}
于 2013-03-12T11:13:21.380 回答
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+")");
}

它正确显示了您想要的内容。

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

于 2013-03-12T11:29:08.993 回答
0

如果您希望添加的 Pieces 显示在您指定的坐标上,则需要将 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);
}
于 2013-03-12T11:11:26.340 回答