paint方法重复执行3次的修复咨询:按二维数组值绘制矩形
嘿,我来帮你搞定这个问题!你的代码里有几个关键问题导致了paint方法重复执行,而且还有一些Swing绘制的规范没遵守,我一步步给你拆解和修复:
问题根源分析
- 重复创建面板实例:你在
start()方法里又new foo(k)添加到窗口,但实际上你已经创建了一个foo实例并调用了它的start()方法,这导致窗口里存在两个独立的foo面板,每个都会触发绘制逻辑,自然会多次执行打印和绘制。 - 错误重写
paint方法:Swing组件的自定义绘制应该用paintComponent而不是直接重写paint——paint方法负责统筹组件的边框、子组件和自身内容的绘制,直接重写它会破坏Swing的绘制流程。 - 未调用父类绘制方法:没有调用
super.paint(g)(或super.paintComponent(g))会导致旧的绘制内容无法被清空,看起来像是重复绘制,同时也会干扰组件背景色等默认绘制逻辑。
修复后的完整代码
import javax.swing.*; import java.awt.*; // 类名首字母大写,符合Java命名规范 public class Foo extends JPanel { Integer[][] k; // 重写paintComponent而非paint,这是Swing自定义绘制的标准方式 @Override protected void paintComponent(Graphics g) { // 必须调用父类方法,清空旧绘制内容、保证背景色等默认逻辑正常执行 super.paintComponent(g); // 空指针防护,避免数组为null/空时崩溃 if (k == null || k.length == 0 || k[0].length == 0) { return; } int row = k.length; int col = k[0].length; System.out.println(row + " " + col); // 调整坐标为网格布局(i*10、j*10),避免矩形都堆在左上角 for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { if (k[i][j] == 1) { g.fillRect(i * 10, j * 10, 10, 10); } } } } public Foo(Integer[][] k) { this.k = k; // 把背景色设置在面板上,而非窗口 this.setBackground(Color.LIGHT_GRAY); // 根据数组大小设置面板首选尺寸,让窗口自动适配 if (k != null && k.length > 0 && k[0].length > 0) { this.setPreferredSize(new Dimension(row * 10, col * 10)); } else { this.setPreferredSize(new Dimension(100, 100)); } } public void start() { JFrame frame = new JFrame(); // 直接添加当前实例this,避免重复创建面板 frame.getContentPane().add(this); // 使用pack()自动适配面板尺寸,比固定setSize更灵活 frame.pack(); frame.setLocationRelativeTo(null); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }
关键修改说明
- 改用
paintComponent:这是Swing组件自定义绘制的标准入口,不会干扰边框、子组件的绘制流程。 - 添加
super.paintComponent(g):每次绘制前清空面板,解决旧内容残留的问题,同时保证背景色正常显示。 - 修复实例重复问题:
start()里直接添加当前this,确保只有一个面板实例在窗口中。 - 优化坐标与窗口尺寸:把矩形坐标改为
i*10和j*10,让二维数组的1对应网格中的矩形;用pack()代替固定setSize,窗口会自动适配面板的实际大小。
现在你再调用new Foo(cnv).start(),就不会出现paint方法重复执行多次的问题了,绘制的矩形也会按网格正常排列~
内容的提问来源于stack exchange,提问作者Leo S
相关产品推荐
相关产品推荐

