現象:用 Frame (AWT) 繪球動畫正常,換成 JFrame (Swing) 後出現殘影/多個球重疊。
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()
}
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();
super.xxx(g),保證清屏與雙緩衝機制生效。paintComponent,repaint() 觸發重繪。JPanel,加入 JFrame,符合 Swing 輕量級組件架構。理解 AWT Frame 自動清屏與 Swing JFrame/JPanel 需顯式 super.paintComponent 清屏的差異,是避免殘影的關鍵。