首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Java Swing 動畫繪球:JFrame 與 Frame 的 paint 重繪差異與 super.paint() 關鍵作用

     編輯:程式設計綜合問答

現象:用 Frame (AWT) 繪球動畫正常,換成 JFrame (Swing) 後出現殘影/多個球重疊。

根本原因:Swing 雙緩衝與 paintComponent 鏈

  • Frame.paint(Graphics):AWT 重繪整個窗口,**默認清屏** (填充背景色),故每幀自動覆蓋上一幀。
  • JFrame 繼承 Frame,但其 paint 內部調用 paintComponent、paintBorder、paintChildren,**默認不清屏** (為了雙緩衝性能與組件疊加)。
  • 直接重寫 JFrame.paint 繪球,**未調用 super.paint(g)** → 父類清屏邏輯被跳過 → 上一幀球體殘留在緩衝區 → 疊加顯示多個球。

修正代碼


public class BallAnimation extends JFrame {
    int x = 50, y = 50;
    
    @Override
    public void paint(Graphics g) {
        super.paint(g); // 關鍵:調用父類 paint,執行清屏、雙緩衝交換、子組件繪製
        g.setColor(new Color(122,122,123));
        g.fillOval(x, y, 50, 50);
        y += 50; // 更新位置 (實際應在 Timer 中更新並 repaint)
    }
    
    // 正規 Swing 動畫寫法:繼承 JPanel 重寫 paintComponent
    // 並在 Timer/線程中 update 狀態 -> repaint()
}

最佳實踐:繼承 JPanel 而非 JFrame


class BallPanel extends JPanel {
    int x=50, y=50;
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // 清屏 (填充背景色)
        g.setColor(new Color(122,122,123));
        g.fillOval(x, y, 50, 50);
    }
    public void moveBall() { y += 10; repaint(); }
}

// 主程序
JFrame frame = new JFrame();
BallPanel panel = new BallPanel();
frame.add(panel);
frame.setSize(400,400);
frame.setVisible(true);

Timer timer = new Timer(50, e -> panel.moveBall());
timer.start();

核心原則

  1. 重寫繪製方法必須調用 super.xxx(g),保證清屏與雙緩衝機制生效。
  2. 動畫邏輯分離:狀態更新在 Timer/線程,繪製在 paintComponent,repaint() 觸發重繪。
  3. 自定義繪製組件繼承 JPanel,加入 JFrame,符合 Swing 輕量級組件架構。

理解 AWT Frame 自動清屏與 Swing JFrame/JPanel 需顯式 super.paintComponent 清屏的差異,是避免殘影的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved