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

Java Swing自定义JComponent添加到JPanel后不显示问题咨询

问题根因

自定义JComponent不显示是违反Swing基础开发规范导致的,具体问题点:

  • 错误重写了paint方法,没有重写正确的绘制方法paintComponent,且没有调用父类绘制逻辑,破坏了Swing的绘制链
  • 没有给自定义的Player组件设置首选尺寸,Swing布局管理器计算得到的组件尺寸为0*0,不会分配渲染空间
  • Swing组件初始化没有放在事件调度线程(EDT)中执行,存在渲染偶发失效的线程安全隐患
  • 关闭窗口的常量调用写法不规范,虽然不影响本次运行,但属于易出错的写法
修正代码

Player组件类修正

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JComponent;

public class Player extends JComponent{
    
    public Player() 
    {
        // 为组件设置首选尺寸,大小覆盖要绘制的矩形范围
        setPreferredSize(new Dimension(200, 200));
    }
   
    @Override
    protected void paintComponent(Graphics g)
    {  
        // 必须先调用父类方法完成默认背景等绘制逻辑
        super.paintComponent(g);
        g.setColor(Color.green);  
        // 绘制坐标相对于当前组件的左上角,不是父容器的左上角
        g.fillRect(40,40,150,150);  
    }  
}

Game面板类(无需大改,保持原有逻辑即可)

import java.awt.Color;
import java.awt.Dimension;
import javax.swing.JPanel;

public class Game extends JPanel{

    public Game() 
    {
        this.setBackground(Color.yellow);
        this.setPreferredSize(new Dimension(500,500));
        Player p = new Player();
        this.add(p);
    }
    
}

Launcher启动类修正

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Launcher {

    public static void main(String[] args) {
        // 所有Swing界面操作必须在事件调度线程中执行,避免线程安全导致的渲染异常
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Key Collector Demo");
            frame.add(new Game());
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }

}
开发注意事项
  • 自定义Swing组件绘制时,永远优先重写paintComponent而非paint:paint是Swing的顶层绘制入口,会依次调用paintComponent(绘制组件本身)、paintBorder(绘制边框)、paintChildren(绘制子组件),直接重写paint很容易跳过必要的绘制逻辑,出现渲染异常
  • 自定义轻量级组件必须主动返回合适的首选尺寸,否则大部分布局管理器会默认给组件分配0*0的空间,组件不会显示
  • 所有Swing组件的创建、修改操作都要放到EDT线程中执行,Swing本身不是线程安全的,跨线程操作UI会出现偶发的不渲染、卡死、脏绘问题
  • 绘制方法中的坐标是相对于当前组件自身左上角的,不要直接使用父容器的坐标计算绘制位置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 12:57:13