SWT(Standard Widget Toolkit)是 Eclipse 平台的原生 GUI 元件庫,提供 Write Once, Run Anywhere 的原生觀感與穩定效能。相較 AWT/Swing,SWT 元件更豐富、平台表現更穩定、Bug 更少。本文從基礎架構、佈局管理、2D 繪圖到 OpenGL 3D 整合,完整涵蓋 SWT 核心技術。
import org.eclipse.swt.widgets.*;
public class HelloWorld {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);
shell.setText("Hello World");
shell.setSize(200, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
readAndDispatch()/sleep() 手動處理事件,異於 Swing 事件驅動dispose()),父釋放子跟著釋放new Widget(parent, styleBit),Style Bit 以位元運算組合(如 SWT.SINGLE | SWT.BORDER)| 佈局 | 特性 | 適用場景 | LayoutData |
|---|---|---|---|
| FillLayout | 單行/單列,等寬高,不支援邊距/換行 | 計算機面板、工具列按鈕 | 無 |
| RowLayout | 類 FlowLayout,支援換行、邊距、間距 | 表單欄位排列、動態內容 | RowData(寬/高) |
| GridLayout | 網格狀,功能最強大也最複雜 | 複雜表單、對話框、需精確對齊 | GridData(跨欄/列、對齊、縮放) |
| FormLayout | 依附關係定位(附著於邊緣/其他控制項) | 精密對齊、響應式視窗 | FormData |
| StackLayout | 疊層,同 CardLayout,一次顯示一層 | Wizard、分頁切換 | 無 |
建議:GridLayout 複雜度高,建議搭配視覺化工具(如 WindowBuilder)設計,手寫僅限簡單案例。
GC 封裝所有繪圖操作,可繪製於任何實作 Drawable 的物件(Control、Image、Display、Printer)。
Image image = new Image(display, "C:/music.gif");
GC gc = new GC(image);
gc.drawLine(0, 0, bounds.width, bounds.height);
gc.drawLine(0, bounds.height, bounds.width, 0);
gc.dispose(); image.dispose(); // 必須釋放
shell.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle area = shell.getClientArea();
e.gc.drawLine(0, 0, area.width, area.height);
}
});
drawLine、drawPolyline、drawPolygon、drawRectangle、drawRoundedRectangle、drawOval、drawArcsetLineStyle(SOLID/DASH/DOT/DASHDOT)、setLineWidthdrawText(處理 \t \n)、drawString(原樣輸出)、textExtent/stringExtent 計算尺寸fillRectangle、fillRoundRectangle、fillOval、fillArc、fillGradientRectangle(漸層)setClipping(x,y,w,h) 限制可繪區域setXORMode(true) 像素級異或運算drawImage(Image, x, y),支援 GIF/BMP/JPG/PNG/TIFFCanvas:專為繪圖設計的 Control 子類,建議繼承建立自訂繪圖元件。
Eclipse 3.2+ 整合 org.eclipse.swt.opengl,核心類別:
resize()、dispose()public class GLScene extends Canvas {
private GLContext context;
public GLScene(Composite parent) {
super(parent, SWT.NONE);
context = new GLContext(this);
addListener(SWT.Resize, e -> context.resize());
addListener(SWT.Dispose, e -> context.dispose());
setSize(parent.getClientArea().width, parent.getClientArea().height);
}
protected void initGL() {
GL gl = context.getGL();
gl.glClearColor(0, 0, 0, 0);
gl.glEnable(GL.GL_DEPTH_TEST);
gl.glDepthFunc(GL.GL_LEQUAL);
gl.glShadeModel(GL.GL_SMOOTH);
gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, GL.GL_NICEST);
}
public void render() {
if (context == null || context.isDisposed()) return;
context.makeCurrent();
GL gl = context.getGL();
drawScene(gl);
context.swapBuffers();
}
protected void drawScene(GL gl) {
gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
gl.glLoadIdentity();
// 子類別覆寫實作具體繪圖
}
}
重複物件(如圖表圓柱體)使用 Display List:
int list = gl.glGenLists(1);
gl.glNewList(list, GL.GL_COMPILE);
// 繪製圓柱體:gluDisk(底) + gluCylinder(身) + glTranslated + gluDisk(頂)
gl.glEndList();
// 繪製時:
gl.glCallList(list);
背景執行緒每 100ms 呼叫 render(),達 10 FPS 動畫效果。
SWT 以原生效能、豐富元件、穩定跨平台著稱。掌握 GC 2D 繪圖 可滿足大多數客製化 UI 需求;OpenGL 整合 則開啟高效能 3D 視覺化大門。關鍵在於:理解資源管理(dispose)、事件迴圈、佈局機制,並善用視覺化工具輔助複雜介面設計。