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

为何repaint()方法未调用paintComponent()?矩形无法显示

问题原因与解决步骤

核心问题:未将GameWindow面板添加到窗口容器

你创建了GameWindow实例(它是JPanel的子类),但在setWindow方法里只创建了JFrame,却没有把当前GameWindow对象添加到JFrame的内容面板中。Swing只会绘制处于容器层级内的组件,所以你的paintComponent方法完全没机会被调用。

修复步骤

  1. 在setWindow方法中添加window.add(this);,将当前GameWindow面板加入到JFrame中。
  2. 移除window.setPreferredSize(...),转而在GameWindow的构造方法里设置自身的首选尺寸:setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));,让JFrame根据面板尺寸自动调整大小。
  3. 删掉paintComponent中的g2.dispose()——传入的Graphics对象由Swing管理,手动释放会导致后续绘制异常。
  4. 在动画循环中添加休眠逻辑,避免无限循环占用过多CPU资源,比如每帧休眠16ms(约60帧/秒)。

修复后的完整代码

Main类

public class Main {
    GameWindow gw;
    
    Main() {
        gw = new GameWindow();
    }
    
    void start() {
        gw.setWindow();
    }

    public static void main(String[] args) {
        new Main().start();
    }
}

GameWindow类

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class GameWindow extends JPanel implements Runnable {
    final int ORIGINAL_TILE_SIZE = 16;
    final int SCALE = 3;
    final int TILE_SIZE = ORIGINAL_TILE_SIZE * SCALE;

    final int MAX_SCREEN_COLUMNS = 16;
    final int MAX_SCREEN_ROWS = 12;
    final int SCREEN_WIDTH = TILE_SIZE * MAX_SCREEN_COLUMNS;
    final int SCREEN_HEIGHT = TILE_SIZE * MAX_SCREEN_ROWS;

    Thread animation;

    public GameWindow() {
        // 面板自身设置首选尺寸
        setPreferredSize(new Dimension(SCREEN_WIDTH, SCREEN_HEIGHT));
        setBackground(Color.black);
    }

    void setWindow() {
        JFrame window = new JFrame();

        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        window.setResizable(false);
        window.setTitle("Avontuur");

        // 关键:将当前面板添加到窗口容器
        window.add(this);

        ImageIcon icon = new ImageIcon("C:\\Users\\Rick\\Desktop\\Star.png");
        window.setIconImage(icon.getImage());
        window.pack();

        window.setLocationRelativeTo(null);
        window.setVisible(true);

        startAnimation();
    }

    void startAnimation() {
        animation = new Thread(this);
        animation.start();
    }

    @Override
    public void run() {
        while (animation != null) {
            update();
            repaint();
            
            // 添加休眠控制帧率
            try {
                Thread.sleep(16);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    
    public void update() {
        
    }
    
    @Override
    public void paintComponent(final Graphics g) {
        super.paintComponent(g);
        
        Graphics2D g2 = (Graphics2D)g;
        
        g2.setColor(Color.white);
        g2.fillRect(100, 100, TILE_SIZE, TILE_SIZE);
        
        // 不要手动释放传入的Graphics对象
        // g2.dispose();
    }
}

额外注意事项

  • 保持paintComponent上的@Override注解,编译器会帮你校验方法签名是否符合Swing的要求。
  • repaint()方法会自动将绘制请求放入Swing的事件调度线程(EDT)中执行,无需手动处理线程同步问题。

内容的提问来源于stack exchange,提问作者Rickvdp

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:05:27