2013-03-12 51 views
0

我想在Swing中实现俄罗斯方块,因为我试图绘制每个矩形相邻的矩形,但第二个矩形不会与第一个矩形相邻。如何在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); 
    } 
} 

回答

2

如果的getPreferredSize()返回任何小于50,50则没有在屏幕

显示出来。这是因为你已经设置了一个60 x坐标为“红“Piece,但组件的首选大小宽度为50,因此该组件从屏幕上拉出。

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

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

无论什么问题,不使用LayoutManager是_解决方案 – kleopatra 2013-03-12 11:30:56

1
  • 覆盖getPreferredSizeJPanel,否则JPanel返回零Dimension

  • 把所有Objects到阵列

  • paintComponent仅环阵

  • 使用Swing Timer(只有一个实例),用于动画

  • example about all a.m. points

+1

+1为Swing Timer – Reimeus 2013-03-12 11:14:24

1

总的问题是一个Swing布局问题。你的mainPanel JPanel有一个默认的布局,FlowLayout,试图安排你添加到它的每个东西(Piece)。每件作品的paintComponent将仅控制自己的绘画,而不是整个mainPanel。所以你的小块没有被绘制相对于整个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; 
     } 
    } 
} 
1

这里有一个逻辑上的错误。您正在使用paintComponent()方法绘制Piece,但您要给出的起始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+")"); 
} 

它正确地显示你想要的。

它也解释了为什么较小的大小不起作用,在当前组件的情况下不是父组件。