我正在尝试在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);
}
}
答案 0 :(得分:2)
如果getPreferredSize()返回小于50,50的任何内容,则屏幕上不会显示任何内容
这是因为你为" red"设置了一个60的X坐标。 Piece
但组件的首选大小宽度为50,因此组件将在屏幕外绘制。
要添加组件,您只需在Piece
处绘制所有0, 0
个组件,然后让布局管理器负责定位。除此之外,鉴于这是一个俄罗斯方块游戏,你应该考虑在一个组件上绘制所有组件,并使用Swing Timer来操作这些组件。
答案 1 :(得分:1)
覆盖getPreferredSize
的{{1}},否则JPanel
返回零JPanel
将所有Dimension
放入数组
Objects
循环内
使用paintComponent
(只有一个实例)进行动画
答案 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);
}