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

Java AWT&Swing双球动画问题:secondBall无法更新位置

问题原因

调用secondBall.action()时触发空指针异常,核心原因是secondBall未设置边界框(BoundingBox)。在Ball类的constrain()方法中,会访问box对象的属性,但secondBall的box始终为null,导致运行时抛出NullPointerException;即使没有报错,不设置边界框也会让小球无法正确触发边界反弹逻辑。

修复步骤

1. 初始化时给secondBall设置边界框

在BallPanel的构造方法中,创建完secondBall后补充边界框设置:

public BallPanel(int width, int height) {
    this.width = width;
    this.height = height;

    ball = new Ball( width / 10, height / 5, 5, 5 );
    secondBall = new Ball( width / 10, height / 5, 5, 5 );

    // 给两个球都设置初始边界框
    ball.setBoundingBox( new Rectangle( 0, 0, width, height ) );
    secondBall.setBoundingBox( new Rectangle( 0, 0, width, height ) );

    timer.start();
}

2. 窗口 resize 时同步更新secondBall的边界框

修改wasResized()方法,确保窗口大小变化后第二个球的边界也能同步更新:

public void wasResized( ) {
    ball.setBoundingBox(new Rectangle(0, 0, getWidth(), getHeight()));
    secondBall.setBoundingBox(new Rectangle(0, 0, getWidth(), getHeight()));
}

3. 启用secondBall的位置更新逻辑

取消actionPerformed中secondBall.action()的注释,让第二个球的位置能正常更新:

public void actionPerformed(ActionEvent e) {
    if(width != getWidth() || height != getHeight())
        wasResized();

    ball.action();
    secondBall.action(); // 现在可正常执行
    repaint();
}
额外优化建议

paintComponent方法中每次重绘都调用setDiameter属于冗余操作,建议将直径设置移到BallPanel构造方法中一次性完成:

public BallPanel(int width, int height) {
    // ... 其他初始化代码 ...
    ball.setDiameter(15);
    secondBall.setDiameter(10);
    timer.start();
}

随后在paintComponent中移除重复的直径设置,只保留绘制逻辑:

public void paintComponent( Graphics g ) {
    g.setColor( Color.black );
    g.fillRect( 0, 0, getWidth(), getHeight() );

    ball.paint(g);
    secondBall.paint(g);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 06:01:29