SWT 的 Graphics 體系提供豐富的圖像處理能力。本文展示兩個經典特效:
ImageData imageData = new ImageData("C:/icons/eclipse.jpg");
byte[] alphaValues = new byte[imageData.height * imageData.width];
for (int j = 0; j < imageData.height; j++) {
for (int i = 0; i < imageData.width; i++) {
// 左側不透明 (255) → 右側全透明 (0)
alphaValues[j * imageData.width + i] = (byte) (255 - 255 * i / imageData.width);
}
}
imageData.alphaData = alphaValues;
final Image image = new Image(display, imageData);
alphaData 陣列長度必須等於 width × height,每個位元組對應一個像素的 Alpha 值(0=全透明,255=不透明)。此例建立線性水平漸變,左側完整顯示圖片,右側逐漸消失。
Canvas canvas = new Canvas(shell, SWT.NULL);
canvas.addPaintListener(e -> e.gc.drawImage(image, 10, 10));
// 視窗關閉時釋放
shell.addShellListener(new ShellAdapter() {
public void shellClosed(ShellEvent e) { image.dispose(); }
});
使用 Canvas 而非 Label 可自訂繪製邏輯;PaintListener 確保視窗重繪時正確渲染。
ImageLoader loader = new ImageLoader();
ImageData[] frames = loader.load("C:/icons/eclipse-ani.gif");
// frames[0] 為邏輯螢幕尺寸,後續幀包含 x/y/delayTime/disposalMethod
Image canvasImage = new Image(display, frames[0].width, frames[0].height);
GC gc = new GC(canvasImage);
ImageLoader.load 回傳陣列,frames[0] 為標頭資訊,實際幀從 frames[1] 開始(視 GIF 結構而定)。每幀包含:
x, y:相對邏輯螢幕的繪製位置delayTime:顯示時間(單位:百分之一秒,需 ×10 轉毫秒)disposalMethod:下一幀前如何處理當前幀(還原背景/保留/還原上一幀)Thread animThread = new Thread() {
int frameIndex = 0;
public void run() {
while (!isInterrupted()) {
frameIndex %= frames.length;
ImageData frameData = frames[frameIndex];
display.asyncExec(() -> {
Image frame = new Image(display, frameData);
gc.drawImage(frame, frameData.x, frameData.y);
frame.dispose();
canvas.redraw(); // 觸發 PaintEvent
});
try { Thread.sleep(frameData.delayTime * 10); }
catch (InterruptedException e) { return; }
frameIndex++;
}
}
};
animThread.start();
關鍵點:
display.asyncExec。Image 繪製後立即 dispose(),避免記憶體洩漏。interrupt() 結束,配合 ShellListener.shellClosed 確保資源釋放。canvas.addPaintListener(e -> e.gc.drawImage(canvasImage, 0, 0));
動畫執行緒持續更新 canvasImage 內容,PaintListener 僅負責將最新畫面繪製到螢幕。
shell.addShellListener(new ShellAdapter() {
public void shellClosed(ShellEvent e) {
animThread.interrupt();
gc.dispose();
canvasImage.dispose();
// 釋放所有幀 Image(若有預載)
}
});
Image 物件,播放時直接 gc.drawImage(preloadedImages[i], ...),省去重複建構開銷。disposalMethod 決定是否清除畫布或還原上一幀,本範例為簡化直接覆蓋繪製。ImageData 像素尺寸與邏輯座標可能不符,建議使用 ImageData.scaledTo 或啟用 SWT 自動縮放。Alpha 通道操作與多幀動畫是 SWT 圖形程式設計的基礎技能。掌握 ImageData.alphaData、ImageLoader、GC 雙緩衝繪製、asyncExec 執行緒協作與資源釋放模式,即可實作豐富的視覺效果,為桌面應用增添專業質感。