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

为何JPanel需手动更新才显示组件?多种尝试均无效

问题解决思路

核心问题1:错误重写了paint()方法

JPanel作为Swing轻量级组件,应当重写paintComponent(Graphics g)而非paint(Graphics g)。paint()方法负责统筹组件的完整绘制流程(含边框、子组件渲染),直接重写会干扰文本框、按钮等子组件的正常渲染逻辑,导致它们需触发重绘(比如点击操作)才会显示。

修改XupLoginPanel的绘制方法:

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g); // 必须调用,保证组件背景与子组件绘制基础

    int tx = (int)(this.getWidth() / 32) + 2;
    int ty = (int)(this.getHeight() / 32) + 2;
    
    for (int i = 0; i < tx; i++) {
        for (int j = 0; j < ty; j++) {
            g.drawImage(this.images[0], i * 32, j * 32, null);
        }
    }
    g.drawImage(this.images[1], this.getWidth() / 2 - 256, 25, null);
    
    g.setColor(Color.lightGray);
    tx = this.getWidth() / 2 - 80;
    ty = 130;
    int w = (this.getWidth() / 2 + 80) - tx;
    int h = 150;
    g.fillRect(tx, ty, w, h);
    
    g.setColor(Color.black);
    g.drawString("Username:", tx + 45, ty + 20);
}

核心问题2:Swing UI操作未在事件调度线程(EDT)执行

Swing所有组件的创建、修改操作必须在EDT中进行,否则会引发渲染异常、组件不显示等问题。你的XupWindow构造函数直接在主线程执行,需用SwingUtilities.invokeLater()包裹启动逻辑。

添加主方法的EDT包裹(假设启动类为Launcher):

public static void main(String[] args) {
    SwingUtilities.invokeLater(() -> {
        new XupWindow();
    });
}

同时调整XupWindow构造函数的执行顺序,将setVisible(true)放到所有组件添加、配置完成后:

public XupWindow() {
    super("Minecraft Launcher");
    this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    this.launcher = new Launcher();
    this.p_login = new XupLoginPanel();
    this.setIconImage(this.p_login.images[2]);
    
    this.addComponentListener(new ComponentAdapter() {
        public void componentResized(ComponentEvent e) {
            p_login.updateOnResize();
            p_login.repaint(); // 仅需repaint()即可,无需validate和updateUI
        }
    });
    
    this.add(this.p_login);
    this.pack();
    
    // 所有配置完成后再显示窗口
    this.setVisible(true);
    
    // 移除sleep这类临时修复代码
}

其他优化点

  • 删除XupWindow中多余的validate()、updateUI()调用:repaint()已足够触发组件重绘,updateUI()仅用于更换外观风格时,此处无需使用。
  • 若图片体积较大,可考虑异步加载避免阻塞EDT,但当前问题中这并非主要诱因。

按上述修改后,JPanel及子组件应能正常显示,无需点击激活。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 06:06:29