SWT 提供 org.eclipse.swt.browser.Browser 元件,可在 Java 桌面應用中直接嵌入原生瀏覽器引擎(Windows 上為 Edge/WebView2、Linux 上為 WebKitGTK、macOS 上為 WebKit)。本文完整解析一個功能齊全的簡易瀏覽器範例,涵蓋工具列導航、網址列、載入進度條、狀態列、標題同步、彈出視窗處理與動畫載入指示器。
主類別 BrowserExample 採用 FormLayout 排版,主要 UI 元件包括:
try {
browser = new Browser(parent, SWT.NONE);
browser.setLayoutData(data);
} catch (SWTError e) {
Label label = new Label(parent, SWT.CENTER | SWT.WRAP);
label.setText("瀏覽器元件無法建立,請確認系統已安裝 WebView2 或 WebKitGTK");
label.setLayoutData(data);
}
若系統缺少瀏覽器引擎,Browser 建構子會拋出 SWTError,此處優雅降級顯示提示訊息。
Listener listener = new Listener() {
public void handleEvent(Event event) {
ToolItem item = (ToolItem) event.widget;
if (item == itemBack) browser.back();
else if (item == itemForward) browser.forward();
else if (item == itemStop) browser.stop();
else if (item == itemRefresh) browser.refresh();
else if (item == itemGo) browser.setUrl(location.getText());
}
};
location.addListener(SWT.DefaultSelection, e -> browser.setUrl(location.getText()));
browser.addProgressListener(new ProgressListener() {
public void changed(ProgressEvent event) {
if (event.total == 0) return;
int ratio = event.current * 100 / event.total;
progressBar.setSelection(ratio);
busy = event.current != event.total;
if (!busy) { index = 0; canvas.redraw(); }
}
public void completed(ProgressEvent event) {
itemBack.setEnabled(browser.isBackEnabled());
itemForward.setEnabled(browser.isForwardEnabled());
progressBar.setSelection(0);
busy = false; index = 0; canvas.redraw();
}
});
同步更新工具列按鈕啟用狀態,提供直觀的歷史導航回饋。
display.asyncExec(new Runnable() {
public void run() {
if (canvas.isDisposed()) return;
if (busy) {
index++; if (index == images.length) index = 0;
canvas.redraw();
}
display.timerExec(150, this);
}
});
使用 display.timerExec 每 150ms 重繪 Canvas,形成循環動畫;載入完成自動停止。
browser.addTitleListener(e -> shell.setText(e.title + " - 瀏覽器範例"));
browser.addStatusTextListener(e -> status.setText(e.text));
browser.addOpenWindowListener(new OpenWindowListener() {
public void open(WindowEvent event) {
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());
Browser browser = new Browser(shell, SWT.NONE);
initialize(display, browser); // 遞迴註冊相同監聽器
event.browser = browser;
}
});
browser.addVisibilityWindowListener(new VisibilityWindowListener() {
public void show(WindowEvent event) {
Browser b = (Browser) event.widget;
Shell s = b.getShell();
if (event.location != null) s.setLocation(event.location);
if (event.size != null) s.setSize(s.computeSize(event.size.x, event.size.y));
s.open();
}
});
browser.addCloseWindowListener(e -> ((Browser)e.widget).getShell().close());
完整支援 window.open()、視窗顯示/隱藏/關閉事件,實現多標籤/彈出視窗行為。
public void dispose() { freeResources(); }
void freeResources() {
if (images != null) {
for (Image img : images) if (img != null) img.dispose();
images = null;
}
}
程式採用單一類別封裝所有邏輯,main 方法建立 Display、Shell 並實例化 BrowserExample,最後進入標準事件迴圈。圖片資源路徑為 C:/icons/web/go.gif 等,實際部署時建議改用 ImageDescriptor.createFromFile 或 ClassLoader 獲取資源。
display.asyncExec 確保安全。Browser 內部持有原生資源,視窗關閉時務必呼叫 dispose()。本範例展示了 SWT Browser 元件的完整應用:從基本導航、進度監控、動畫指示,到彈出視窗生命週期管理。開發者可在此基礎上擴充書籤、歷史記錄、開發者工具整合等進階功能,快速構建桌面端網頁檢視或混合應用。