PaintComponent 中断网格绘制

PaintComponent disrupting grid drawing

我不熟悉 Java 以及用户界面,我对 Java 图形有疑问。我想要实现的是在 JPanel 上绘制网格,然后将自定义组件绘制到网格中。

这是我要在其上绘制网格的class(它的基础扩展了 JPanel)。

public class RectGridPanel extends GridPanel
{

    List<Rectangle> rects;  
    
    public RectGridPanel(Simulator sim)
    {
        super(sim);
        
        this.rects = new ArrayList<Rectangle>();        
        
        this.setLayout(new GridLayout(20,20));
        
        for(int x = 1; x < 801; x += 40)
        {
            for(int y = 2; y < 801; y += 40)
            {
                Cell newCell = new RectCell(x, y, sim);
                this.add(newCell);
            }
        }
        
    }
    
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(Color.BLACK);
        for(int x = 1; x < 801; x += 40)
        {
            for(int y = 2; y < 801; y += 40)
            {
                Rectangle rect = new Rectangle(x, y, 40, 40);
                g2.draw(rect);
                rects.add(rect);
            }
        }
    }
}

这是我要在网格内绘制的单元格:

public class RectCell extends Cell
{
    Rectangle shape;
    
    public RectCell(int x, int y, Simulator sim)
    {
        super(x, y, sim);
        shape = new Rectangle(x, y, CELL_SIZE, CELL_SIZE);
    }
    
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(Color.BLACK);
        g2.fill(shape);
    }
}

所以网格本身绘制得很好,但是一旦我尝试在其中创建单元格,它就会像这样被打乱:

不清楚您要达到什么目的。 RectCell的原因是什么?为什么不直接在 RectGridPanel 中绘制形状? paintComponent 中的嵌套循环不是一个好主意。请注意,paintComponent 被调用的频率非常高,每次您使用新对象增加 rects 列表时。以前绘制的矩形丢失(qraphicaly),具有相同参数的新矩形正在刷新列表。

public class RectCell extends Cell
{
    Rectangle shape;
    
    public RectCell(int x, int y, Simulator sim)
    {
        super(x, y, sim);
        shape = new Rectangle(x, y, CELL_SIZE, CELL_SIZE);
    }
    
    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setPaint(Color.BLACK);
        g2.fill(shape);
    }
}

传递给此 paintComponent() 函数的 Graphics 对象定义当前 RectCell 可以绘制的屏幕 space。坐标系相对于 RectCell 的左上角,因此绘制背景应始终从 x = 0y = 0 或其他有意义的值开始。这里的坐标并不像你想象的那样是相对于父组件的。

更好的是,设置背景颜色并让 Swing 负责绘制它,而不是您自己绘制矩形。