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

Java Swing弹跳小球启动线程后初始坐标不生效问题

问题根源

你碰到的核心问题是线程启动时机过早+首次获取画板尺寸为0触发了边界修正:

  • 你在Board类的构造函数里就直接启动了移动线程,但此时Board组件还没被添加到JFrame完成布局渲染,第一次调用getWidth()/getHeight()拿到的返回值是0
  • 线程第一次循环就会执行坐标更新+边界判断:你初始的X=243、Y=104,判断X + radius > width(243+4>0)成立,直接触发边界修正逻辑把X重置为radius=4,同理Y也会被重置为4,自然就跑到左上角了。

修复方案

两个改法选一个即可,推荐第二种更符合Swing开发规范:

方案1:新增尺寸有效性判断,未完成初始化时不更新坐标

修改线程内的逻辑即可,原有代码其余部分不用动:

public void run() {
    while (true) {
        repaint();
        width = getWidth();
        height = getHeight();
        // 新增判断:宽高未初始化完成时跳过坐标更新
        if (width <= 0 || height <= 0) {
            try {
                Thread.sleep(10);
            } catch(InterruptedException ex) {}
            continue;
        }
        // 原有坐标更新、边界判断逻辑保持不变
        X = X + dx ;
        Y = Y + dy;
        if (X - radius < 0) {
            dx = -dx; 
            X = radius;
        } else if (X + radius > width) {
            dx = -dx;
            X = width - radius;
        }

        if (Y - radius < 0) {
            dy = -dy;
            Y = radius;
        } else if (Y + radius > height) {
            dy = -dy;
            Y = height - radius;
        }
        
        try {
            Thread.sleep(10);
        } catch(InterruptedException ex) {}
    }
}

也可以选择把线程启动逻辑移到main方法的frame.setVisible(true)之后,此时组件已经完成渲染,宽高是正确值,也能解决问题。

方案2:替换自定义线程为Swing Timer(避免Swing线程安全问题)

Swing官方更推荐用javax.swing.Timer处理界面周期性更新,不需要自己管理线程,修改构造函数即可:

public Board() {
    // 删掉原有自定义Thread的代码,替换为Timer实现
    javax.swing.Timer timer = new javax.swing.Timer(10, e -> {
        width = getWidth();
        height = getHeight();
        if (width <=0 || height <=0) return;
        
        X = X + dx ;
        Y = Y + dy;
                    
        if (X - radius < 0) {
            dx = -dx; 
            X = radius;
        } else if (X + radius > width) {
            dx = -dx;
            X = width - radius;
        }

        if (Y - radius < 0) {
            dy = -dy;
            Y = radius;
        } else if (Y + radius > height) {
            dy = -dy;
            Y = height - radius;
        }
        repaint();
    });
    timer.start();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 18:06:05