首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java Swing 彈跳球動畫完整實現:多執行緒與雙緩衝繪圖

     編輯:Java 相關知識

Java Swing 彈跳球動畫從零構建

本文完整展示如何使用 Java Swing 構建一個可調速的多球彈跳動畫。專案涵蓋視窗建立、自訂繪圖畫布、定時器驅動動畫迴圈、鍵盤/滑鼠事件處理、焦點管理與動態速度調整等核心 GUI 程式設計技術。

架構設計

  • 主視窗 (BallsJFrame): 繼承 JFrame,包含畫布區域與南部控制面板(JSpinner 調整延遲)
  • 繪圖畫布 (BallsCanvas): 繼承 Canvas,實作 ActionListener(定時器回調)與 FocusListener(焦點控制動畫暫停/恢復)
  • 球體模型 (Ball): 內部靜態類,封裝座標、速度方向、顏色屬性

核心程式碼解析

1. 主視窗初始化與事件綁定

public class BallsJFrame extends JFrame implements ChangeListener {
    private BallsCanvas ball;
    private JSpinner spinner;

    public BallsJFrame() {
        super("彈跳球動畫");
        setBounds(300, 200, 400, 300);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        Color[] colors = {Color.RED, Color.GREEN, Color.BLUE, Color.MAGENTA, Color.CYAN};
        ball = new BallsCanvas(colors, 100); // 初始延遲 100ms
        add(ball, BorderLayout.CENTER);

        JPanel controlPanel = new JPanel();
        controlPanel.add(new JLabel("延遲(ms):"));
        spinner = new JSpinner();
        spinner.setValue(100);
        spinner.addChangeListener(this);
        controlPanel.add(spinner);
        add(controlPanel, BorderLayout.SOUTH);

        setVisible(true);
    }

    @Override
    public void stateChanged(ChangeEvent e) {
        int delay = (Integer) spinner.getValue();
        ball.setDelay(delay); // 動態調整定時器間隔
    }
}

2. 畫布與動畫迴圈核心

class BallsCanvas extends Canvas implements ActionListener, FocusListener {
    private Ball[] balls;
    private Timer timer; // javax.swing.Timer - 事件派發執行緒安全

    public BallsCanvas(Color[] colors, int delay) {
        balls = new Ball[colors.length];
        for (int i = 0, x = 40; i < colors.length; i++, x += 20) {
            balls[i] = new Ball(x, x, colors[i]);
        }
        addFocusListener(this); // 監聽焦點控制動畫
        timer = new Timer(delay, this);
        timer.start();
    }

    public void setDelay(int delay) {
        timer.setDelay(delay);
    }

    @Override
    public void paint(Graphics g) {
        for (Ball ball : balls) {
            g.setColor(ball.color);
            // 更新 X 座標
            ball.x = ball.left ? ball.x - 10 : ball.x + 10;
            // 邊界檢測與反彈
            if (ball.x <= 0 || ball.x >= getWidth() - 24) {
                ball.left = !ball.left;
            }
            // 更新 Y 座標
            ball.y = ball.up ? ball.y - 10 : ball.y + 10;
            if (ball.y <= 0 || ball.y >= getHeight() - 22) {
                ball.up = !ball.up;
            }
            g.fillOval(ball.x, ball.y, 20, 20);
        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        repaint(); // 觸發 paint() 重繪
    }

    @Override
    public void focusGained(FocusEvent e) {
        timer.stop(); // 失去焦點暫停
    }

    @Override
    public void focusLost(FocusEvent e) {
        timer.restart(); // 獲得焦點恢復
    }

    private static class Ball {
        int x, y;
        boolean up, left;
        Color color;
        public Ball(int x, int y, Color color) {
            this.x = x; this.y = y; this.color = color;
            up = left = false; // 初始向右下移動
        }
    }
}

關鍵技術點總結

技術點實現方式優勢
動畫驅動javax.swing.TimerEDT 執行緒安全,自動處理重繪併發
雙緩衝Canvas 原生支援 / 可升級 JPanel消除閃爍
速度控制JSpinner + Timer.setDelay()即時動態調整,無需重建定時器
焦點管理FocusListener + timer.stop/restart視窗非活躍時節省 CPU
邊界反彈座標邊界檢測 + 方向布林旗標邏輯簡單高效

進階優化建議

  • 將 Canvas 升級為 JPanel 並覆寫 paintComponent,獲得更好的雙緩衝支援
  • 引入 Velocity 向量類別取代布林旗標,支援任意角度與速度大小
  • 新增球體碰撞檢測,實現球與球之間的彈性碰撞
  • 使用 BufferStrategy 實現主動式渲染,進一步提升幀率穩定性

此專案展示了 Java Swing 建構互動式動畫應用的完整範式,從模型分離、事件驅動、執行緒安全到使用者體驗細節,是 GUI 程式設計入門與進階的優質實戰教材。

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