0

Swing で Tetris を実装しようとしています。そのため、それぞれに隣接する長方形を描画しようとしていますが、2 番目の長方形が最初の長方形に隣接していません。

また、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し、レイアウト マネージャーに配置を任せることができます。それとは別に、これがテトリスのゲームであることを考えると、すべてのコンポーネントを 1 つのコンポーネントにペイントし、スイング タイマーを使用してピースを操作することを検討する必要があります。

于 2013-03-12T11:08:43.513 に答える
1
  • をオーバーライドgetPreferredSizeしますJPanel。それ以外の場合JPanelはゼロを返しますDimension

  • すべてObjectsを配列に入れます

  • paintComponent配列内のループ内のみ

  • Swing Timerアニメーションに(1つのインスタンスのみ)使用する

  • すべてのamポイントについての例

于 2013-03-12T11:12:23.233 に答える
1

全体的な問題はSwingLayoutの問題です。mainPanel JPanelには、デフォルトのレイアウトFlowLayoutがあり、追加する各もの(Piece)を配置しようとします。各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

ここに 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

追加したピースを指定した座標に表示する場合は、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 に答える