SWT 圖形系統核心在於 org.eclipse.swt.graphics 套件。本文透過「畫圖板」範例,詳細講解 GC(Graphics Context)、Image、Canvas 協作機制,以及解決視窗最小化/遮擋導致繪圖消失的 PaintListener 機制。
Display(螢幕)、Printer(印表機)。Control(所有 UI 控制項)、Image(離屏圖像)。Drawable,封裝所有繪圖方法(drawLine、fillRectangle、drawImage 等)。Device,支援從檔案/資料流載入。// CanvasView.java
public class CanvasView extends ViewPart {
public Canvas canvas;
@Override public void createPartControl(Composite parent) {
canvas = new Canvas(parent, SWT.NONE);
}
@Override public void setFocus() { canvas.setFocus(); }
}
// DrawOvalAction.java (菜單/工具列 Action)
public void run(IAction action) {
IViewPart view = findView("畫圖板");
if (view instanceof CanvasView) {
GC gc = new GC(((CanvasView)view).canvas);
gc.drawOval(80, 50, 100, 100); // x, y, width, height
gc.dispose(); // 必須釋放系統資源
}
}
// DrawGradientAction.java
GC gc = new GC(canvas);
gc.setBackground(display.getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(80, 200, 100, 100, false); // false=垂直漸層
gc.dispose();
// DrawImageAction.java
GC gc = new GC(canvas);
Image img = new Image(display, "E:/img.gif");
gc.drawImage(img, 280, 200);
gc.dispose();
img.dispose(); // Image 亦需手動釋放
直接在 GC 上繪圖屬於「即時模式」,視窗最小化、被遮擋、切換分頁後,SWT 會重繪控制項,導致圖形消失。
public class CanvasView extends ViewPart {
public Canvas canvas;
private List<DrawCommand> commands = new ArrayList<>(); // 自定義命令物件
@Override public void createPartControl(Composite parent) {
canvas = new Canvas(parent, SWT.NONE);
canvas.addPaintListener(e -> {
GC gc = e.gc; // 系統提供的 GC,無需 dispose
for (DrawCommand cmd : commands) {
cmd.execute(gc);
}
});
}
// 供 Action 呼叫
public void addCommand(DrawCommand cmd) {
commands.add(cmd);
canvas.redraw(); // 觸發重繪
}
}
// 命令模式封裝
interface DrawCommand { void execute(GC gc); }
class DrawOvalCmd implements DrawCommand {
private final int x, y, w, h;
public DrawOvalCmd(int x, int y, int w, int h) { this.x=x; this.y=y; this.w=w; this.h=h; }
public void execute(GC gc) { gc.drawOval(x, y, w, h); }
}
// Action 中改為:
view.addCommand(new DrawOvalCmd(80, 50, 100, 100));
| 功能 | 方法範例 |
|---|---|
| 前景/背景色 | gc.setForeground(color); gc.setBackground(color); |
| 線條樣式 | gc.setLineStyle(SWT.LINE_DASH); gc.setLineWidth(2); |
| 文字繪製 | gc.drawText("Hello", 10, 10, true); // true=抗鋸齒 |
| 裁剪區域 | gc.setClipping(x, y, w, h); // 限制繪圖範圍 |
| 變換矩陣 | Transform t = new Transform(display); t.rotate(45); gc.setTransform(t); |
| Alpha 透明度 | gc.setAlpha(128); // 0-255 |
new GC(drawable))必須 dispose()。dispose()。Display.getSystemColor() 取得的系統色彩 不可 dispose。SWT 2D 繪圖核心在於 GC 與 Drawable 的分離設計。掌握 命令模式保留繪圖指令 + PaintListener 重播 模式,即可實現持久化、可縮放、可列印的向量繪圖應用。善用 fillGradientRectangle、drawImage、Transform 等進階 API,能輕鬆構建豐富視覺效果。