雖然 Applet 技術已隨瀏覽器停止支援 Java 外掛而退出歷史舞台,但理解其架構對掌握 Java GUI 程式模型、生命週期管理、以及早期 Web 應用演進仍具教學價值。本文詳細解析 Applet/JApplet 的五大生命週期方法、網頁嵌入方式、與 Swing 整合,並提供動畫範例。
Panel,採用 AWT 組件Applet,內含 JRootPane,支援 Swing 組件與雙重緩衝| 方法 | 觸發時機 | 典型用途 |
|---|---|---|
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 組件,並提供 main 方法方便桌面測試。
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);
});
}
}
init()/start(),將 Applet 當作面板加入 JFrame使用 javax.swing.Timer 定時觸發 repaint(),在 paint() 中繪製隨機位置、顏色、字體的字串。
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);
});
}
}
JApplet 自動啟用,Applet 需手動實作(離屏圖片)避免閃爍| 時代 | 技術 | 特點 |
|---|---|---|
| 1995-2000 | Applet (AWT) | Java Web 應用起點,瀏覽器內執行 Java 位元碼 |
| 1998-2010 | JApplet (Swing) | 豐富 GUI、雙重緩衝、可簽名獲取完整權限 |
| 2000-2015 | Java Web Start (JNLP) | 脫離瀏覽器啟動、沙箱/全權限、自動更新 |
| 2010-至今 | HTML5/JS 框架 | 原生瀏覽器支援、無外掛、跨平台、效能優異 |
| 2018+ | WebAssembly / GraalVM | 瀏覽器執行原生位元碼、Java 編譯為 WASM |