You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

paint方法重复执行3次的修复咨询:按二维数组值绘制矩形

嘿,我来帮你搞定这个问题!你的代码里有几个关键问题导致了paint方法重复执行,而且还有一些Swing绘制的规范没遵守,我一步步给你拆解和修复:

问题根源分析

  1. 重复创建面板实例:你在start()方法里又new foo(k)添加到窗口,但实际上你已经创建了一个foo实例并调用了它的start()方法,这导致窗口里存在两个独立的foo面板,每个都会触发绘制逻辑,自然会多次执行打印和绘制。
  2. 错误重写paint方法:Swing组件的自定义绘制应该用paintComponent而不是直接重写paint——paint方法负责统筹组件的边框、子组件和自身内容的绘制,直接重写它会破坏Swing的绘制流程。
  3. 未调用父类绘制方法:没有调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.06 22:57:42