Java Applet 常用於顯示儲存在 GIF 或 JPEG 格式檔案中的圖像。處理圖像時,需定義 java.awt.Image 物件,並使用 getImage() 方法將圖像檔案與 Image 物件關聯。為了提升顯示效能與流暢度,許多 Applet 採用**雙緩衝技術**:先將圖像完整載入記憶體,再一次性繪製到螢幕上,避免畫面閃爍與不連續顯示。
| 類別/方法 | 用途 |
|---|---|
java.awt.Image | 圖像資料的抽象表示 |
Applet.getImage(URL, String) | 載入圖像:第一參數為基底 URL(通常用 getCodeBase()),第二參數為相對路徑檔名 |
Graphics.drawImage(Image, x, y, ImageObserver) | 繪製圖像:指定左上角座標 (x,y) 與觀察者(通常傳 this 或 null) |
Component.createImage(w, h) | 建立離屏圖像(雙緩衝核心) |
Image.getGraphics() | 取得離屏圖像的繪圖環境 |
imageUpdate(Image, flags, x, y, w, h) | 非同步載入回調:監控圖像載入進度,flags 含 ALL_BITS 表示完成 |
import java.awt.*;
import java.applet.*;
public class ShowImage extends Applet {
Image picture; // 成員變數持有圖像參考
public void init() {
// 載入圖像:getCodeBase() 返回 Applet 所在 URL 目錄
picture = getImage(getCodeBase(), "Image.gif");
}
public void paint(Graphics g) {
// 直接繪製:第四參數 this 註冊 imageUpdate 回調
g.drawImage(picture, 0, 0, this);
}
}
對應 HTML:
<HTML>
<TITLE>Show Image Applet</TITLE>
<APPLET CODE="ShowImage.class" WIDTH=600 HEIGHT=400>
</APPLET>
</HTML>
問題:drawImage() 非同步執行,會建立執行緒一邊載入一邊繪製,導致圖像逐漸顯示(撕裂、閃爍),體驗不佳。
核心思路:離屏繪製 → 載入完成 → 一次性翻轉到螢幕。
import java.awt.*;
import java.applet.*;
public class BackgroundImage extends Applet {
Image picture; // 原始圖像
Image offScreenImage; // 離屏緩衝區
Graphics offScreenGC; // 離屏繪圖環境
boolean imageLoaded = false; // 載入完成旗標
public void init() {
picture = getImage(getCodeBase(), "Image.gif");
// 1. 建立離屏圖像(與 Applet 同尺寸)
offScreenImage = createImage(size().width, size().height);
// 2. 取得離屏繪圖環境
offScreenGC = offScreenImage.getGraphics();
// 3. 在離屏繪製圖像(觸發非同步載入,註冊 this 為觀察者)
offScreenGC.drawImage(picture, 0, 0, this);
}
public void paint(Graphics g) {
if (imageLoaded) {
// 載入完成:直接繪製已就緒的離屏圖像,第四參數 null 避免再次觸發 imageUpdate
g.drawImage(offScreenImage, 0, 0, null);
showStatus("Done");
} else {
showStatus("Loading image...");
}
}
// 非同步載入回調:由 drawImage 內部執行緒定期呼叫
public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) {
if ((infoflags & ALLBITS) != 0) { // 圖像完全載入
imageLoaded = true;
repaint(); // 觸發 paint() 重繪
return false; // 停止後續回調
}
return true; // 繼續監控
}
}
offScreenImage),在離屏環境(offScreenGC)繪製原始圖像。此時螢幕**無任何顯示**。imageUpdate() 回報進度(infoflags)。ALLBITS 標誌 → 設定 imageLoaded=true → 呼叫 repaint() → 返回 false 停止回調。imageLoaded 控制。完成前顯示載入狀態;完成後繪製**離屏圖像**(而非原始 picture),第四參數傳 null 避免重複註冊觀察者。repaint() 觸發的 paint() 直接繪製記憶體圖像,極快。注意:Java Applet 技術已過時(JDK 9 標記棄用,JDK 11 移除),現代 Web 開發請使用:
BufferStrategy、RepaintManager)雙緩衝原理在現代圖形程式設計中依然通用,理解其核心機制有助於解決各類渲染閃爍問題。