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

Java Applet 與 JApplet 詳解:生命週期、網頁嵌入與動畫實作

     編輯:Java 相關知識

前言

雖然 Applet 技術已隨瀏覽器停止支援 Java 外掛而退出歷史舞台,但理解其架構對掌握 Java GUI 程式模型、生命週期管理、以及早期 Web 應用演進仍具教學價值。本文詳細解析 Applet/JApplet 的五大生命週期方法、網頁嵌入方式、與 Swing 整合,並提供動畫範例。

一、Applet 與 JApplet 的關係

  • Applet (java.applet.Applet):AWT 時代基礎類別,繼承 Panel,採用 AWT 組件
  • JApplet (javax.swing.JApplet):Swing 版本,繼承 Applet,內含 JRootPane,支援 Swing 組件與雙重緩衝
  • 兩者無 main 方法,由瀏覽器或 AppletViewer 呼叫生命週期方法啟動

二、五大生命週期方法

方法觸發時機典型用途
init()Applet 首次載入時呼叫一次初始化組件、佈局、載入資源、啟動執行緒
start()Applet 可見時呼叫(含頁面切回、init 後)啟動動畫執行緒、恢復音訊播放、開始定時任務
stop()Applet 不可見時呼叫(切換分頁、最小化視窗)暫停動畫、停止執行緒、釋放資源
destroy()Applet 卸載前呼叫一次釋放所有資源、停止執行緒、關閉連線
paint(Graphics g)需要繪製時呼叫(初始顯示、重繪、調用 repaint)自訂繪圖、動畫幀渲染、呼叫 super.paint(g) 繪製子組件

生命週期流程圖

載入類別 → init() → start() → [可見期間: 重複 paint() / 使用者互動]
                    ↑                      |
                    |---------- stop() ←---┘ (頁面切離)
                                    |
                              destroy() (關閉瀏覽器/卸載)

三、網頁嵌入方式

傳統 <applet> 標籤已棄用,現代改用 <object> 或 Java Network Launch Protocol (JNLP)。歷史嵌入範例:

<applet codebase="." code="HelloApplet" width="400" height="300" name="HelloApplet">
    <param name="name" value="HelloApplet">
</applet>
  • codebase:類別檔案基礎路徑
  • code:主類別名稱(不含 .class)
  • width/height:顯示區域尺寸
  • param:傳遞參數,Applet 內用 getParameter("name") 取得

實際部署常使用 JDK HtmlConverter 工具自動產生跨瀏覽器相容標籤。

四、JApplet 與 Swing 整合範例

以下範例展示 JApplet 使用 Swing 組件,並提供 main 方法方便桌面測試。

範例 1:基本 JApplet 結構

public class HelloApplet extends JApplet {
    @Override
    public void init() {
        // Swing 組件初始化需在 EDT 執行
        try {
            SwingUtilities.invokeAndWait(() -> {
                setLayout(new FlowLayout());
                add(new JButton("按鈕 XXX"));
                add(new JButton("按鈕 YYY"));
                JLabel label = new JLabel("JApplet 測試", SwingConstants.CENTER);
                label.setFont(new Font("微軟正黑體", Font.BOLD, 18));
                add(label, BorderLayout.NORTH);
            });
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override public void start() {
        System.out.println("[Applet] start() 呼叫");
    }

    @Override public void stop() {
        System.out.println("[Applet] stop() 呼叫");
    }

    @Override public void destroy() {
        System.out.println("[Applet] destroy() 呼叫");
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g); // 必須呼叫,繪製子組件
        System.out.println("[Applet] paint() 呼叫");
        g.drawLine(10, 10, 200, 100);
    }

    // 方便桌面測試的 main 方法
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("JApplet 桌面測試");
            JApplet applet = new HelloApplet();
            applet.setPreferredSize(new Dimension(400, 300));
            // 手動觸發生命週期
            applet.init();
            applet.start();
            frame.add(applet);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

關鍵點

  1. SwingUtilities.invokeAndWait:確保組件建立在事件派發執行緒(EDT)
  2. super.paint(g):必須呼叫,否則子組件不會被繪製
  3. main 方法模擬:手動呼叫 init()/start(),將 Applet 當作面板加入 JFrame

五、Applet 動畫實作:彈跳字串

使用 javax.swing.Timer 定時觸發 repaint(),在 paint() 中繪製隨機位置、顏色、字體的字串。

範例 2:動畫 Applet

public class BouncingTextApplet extends Applet {
    private static final String TEXT = "Java 真好玩,學習很有趣!";
    private int nextX, nextY;
    private Color nextColor;
    private Font nextFont;
    private final Random random = new Random(System.currentTimeMillis());

    @Override
    public void init() {
        setBackground(Color.WHITE);
        // 每 200ms 觸發一次重繪
        Timer timer = new Timer(200, e -> {
            nextX = random.nextInt(400);
            nextY = random.nextInt(300);
            nextColor = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
            nextFont = new Font("Serif", Font.BOLD, random.nextInt(48) + 12);
            repaint(); // 排程重繪
        });
        timer.start();
    }

    @Override
    public void paint(Graphics g) {
        // Applet 不需呼叫 super.paint(g)(無雙重緩衝),直接繪製
        g.setColor(nextColor);
        g.setFont(nextFont);
        g.drawString(TEXT, nextX, nextY);
    }

    // 桌面測試 main
    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame("Applet 動畫測試");
            Applet applet = new BouncingTextApplet();
            applet.setPreferredSize(new Dimension(400, 300));
            applet.init();
            applet.start();
            frame.add(applet);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        });
    }
}

動畫關鍵技術

  • Timer:Swing 定時器,事件在 EDT 執行,安全更新 UI 狀態
  • repaint():非同步請求重繪,系統合併多次請求,效能優於直接呼叫 paint
  • 雙重緩衝:JApplet 自動啟用,Applet 需手動實作(離屏圖片)避免閃爍

六、Applet 衰退與現代替代方案

主要衰退原因:安全性風險(沙箱逃逸)、瀏覽器廠商移除 NPAPI 外掛支援、行動裝置不支援、HTML5/JS 生態完善。

七、遷移建議

  1. 教學/舊系統維護:保留 Applet 知識,使用 appletviewer 或桌面模式測試
  2. Web 應用現代化:重寫為 Spring Boot + React/Vue/Angular,或使用 Vaadin(Java 單語言全端)
  3. 桌面應用:遷移至 JavaFX、Swing(獨立應用)、TornadoFX
  4. 跨平台客戶端:考慮 Electron、Flutter、Compose Multiplatform

總結

Applet/JApplet 是 Java 早期 Web 野心的產物,雖已退場,其生命週期管理模型(init/start/stop/destroy)深深影響後續 Servlet、JavaFX、Android Activity 等框架設計。理解 Applet 有助於掌握「容器管理元件生命週期」這一核心軟體架構模式。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
時代技術特點
1995-2000Applet (AWT)Java Web 應用起點,瀏覽器內執行 Java 位元碼
1998-2010JApplet (Swing)豐富 GUI、雙重緩衝、可簽名獲取完整權限
2000-2015Java Web Start (JNLP)脫離瀏覽器啟動、沙箱/全權限、自動更新
2010-至今HTML5/JS 框架原生瀏覽器支援、無外掛、跨平台、效能優異
2018+WebAssembly / GraalVM瀏覽器執行原生位元碼、Java 編譯為 WASM