PaintComponent 破坏网格绘图
Posted
技术标签:
【中文标题】PaintComponent 破坏网格绘图【英文标题】:PaintComponent disrupting grid drawing 【发布时间】:2022-01-03 22:12:25 【问题描述】:我是 Java 和用户界面的新手,但我对 Java 图形有疑问。我想要实现的是在 JPanel 上绘制网格,然后将自定义组件绘制到网格中。
这是我要在其上绘制网格的类(其基础扩展 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);
所以网格本身绘制得很好,但是一旦我尝试在其中创建单元格,它就会像这样被打乱:
【问题讨论】:
如需更好的帮助,请edit添加minimal reproducible example。Cell
和 GridPanel
是什么?
rects.add(rect);
这将在每次调用paintComponent()
时将所有矩形添加到列表中。您应该只在创建时初始化列表一次。
您应该有一张图纸JPanel
负责所有图纸。您使用由一个或多个 Java getter/setter 类组成的逻辑模型来维护板的状态。绘图JPanel
从逻辑模型中读取游戏状态并相应地绘制游戏板。您必须在游戏的每一帧中绘制所有内容。
【参考方案1】:
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
可以绘制的屏幕空间。坐标系相对于RectCell
的左上角,因此绘制背景应始终从x = 0
和y = 0
或其他有意义的值开始。这里的坐标并不像你想象的那样相对于父组件。
更好的是,设置背景颜色并让 Swing 负责绘制它,而不是自己绘制一个矩形。
【讨论】:
我现在尝试使用背景颜色,使用 JPanel 绘制网格并给它们一个边框,然后将它们添加到我在 RectGridPanel 中创建的网格布局中。网格再次工作得很好,但是在我将单元格放在新创建的 JPanel 上之后它变得很奇怪,单元格的大小越小,它们离左上角越远(尽管我猜这只是它们的背景,因为鼠标侦听器附加到它们上可以正常工作)。 @HairyGnome 自从您第一次发布此问题以来,您似乎已经对代码进行了重大更改。如果您仍然需要帮助,我建议发布一个新问题。请务必包含足够的代码,以便我们自己编译和运行它,但不要包含任何与您的问题无关的代码。【参考方案2】:目前尚不清楚您要达到什么目标。 RectCell的原因是什么?为什么不直接在 RectGridPanel 中绘制形状? paintComponent 中的嵌套循环不是一个好主意。请注意,每次使用新对象增加 rects 列表时都会经常调用paintComponent。以前绘制的矩形会丢失(画质),而具有相同参数的新矩形则超出了列表。
【讨论】:
代表每个单元格的组件就可以了。您的建议与为什么不在一个paintComponet()
中绘制所有按钮和标签相同。我们创建类来表示程序中的对象。
是的,你的组件是对的,你可以让 super.paintC... 渲染它们。但是你必须使用 Layout 并定义组件的不同宽度和高度属性,以便 LayoutManager 知道如何渲染。
这可能是问题所在:Cell
不能很好地与 LayoutManager API 配合使用。
我看到使用了 GridLayout。但是 RectCell 中形状的 x/y 定位没有任何意义。每个 RectCell 的定位由 GridLayout 管理,如果 RectCell 中的形状是必需的,它的 x 和 y 应该是静态的。随着每个实例化值的增加,您可以使形状移出组件的绘制区域。
是的,我刚刚注意到同样的事情,并开始按照这些思路写一个答案。一个问题是传递给RectCell.paintComponent()
的Graphics
对象的坐标系定义了对象可以绘制的区域。这不是父 RectGridPanel
的区域。以上是关于PaintComponent 破坏网格绘图的主要内容,如果未能解决你的问题,请参考以下文章