| 維度 | SWT | JFace |
| 窗口基類 | Shell (需自建 Display) | ApplicationWindow (內建生命週期) |
| 控件創建 | 直接 new Button(shell, SWT.PUSH) | 在 createContents(Composite parent) 回調中創建 |
| 事件處理 | addSelectionListener(new SelectionAdapter(){...}) | 同 SWT,但常結合 Viewer 使用 |
| 事件循環 | 手寫 while(!shell.isDisposed()){...} | ApplicationWindow.run() 內建 |
| 適用場景 | 精細控制、非標準窗口、輕量部署 | 標準應用窗口、需快速構建、數據綁定 |
三、實戰:雙版本「記事本」完整代碼走讀
功能:工具欄「新建/打開/保存」+ 多行文本編輯區。
1. SWT 版核心邏輯
public class FirstSWT {
private static Display display;
private static Shell shell;
private static Text text;
private static String currentFile = "";
public static void main(String[] args) {
display = new Display();
shell = new Shell(display, SWT.DIALOG_TRIM | SWT.RESIZE);
shell.setText("SWT 記事本");
shell.setSize(600, 400);
// 工具欄按鈕
Button btnNew = new Button(shell, SWT.PUSH);
btnNew.setBounds(5, 5, 60, 25); btnNew.setText("新建");
Button btnOpen = new Button(shell, SWT.PUSH);
btnOpen.setBounds(70, 5, 60, 25); btnOpen.setText("打開");
Button btnSave = new Button(shell, SWT.PUSH);
btnSave.setBounds(135, 5, 60, 25); btnSave.setText("保存");
// 文本區 (佔滿剩餘空間)
text = new Text(shell, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP);
text.setBounds(5, 35, 580, 340);
// 事件綁定
btnNew.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
currentFile = "";
shell.setText("SWT 記事本");
text.setText("");
}
});
btnOpen.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
FileDialog dlg = new FileDialog(shell, SWT.OPEN);
String file = dlg.open();
if (file != null) {
try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF-8"))) {
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) sb.append(line).append("\n");
text.setText(sb.toString());
currentFile = file;
shell.setText(file);
MessageBox mb = new MessageBox(shell, SWT.ICON_INFORMATION);
mb.setMessage("打開成功"); mb.open();
} catch (Exception ex) {
new MessageBox(shell, SWT.ICON_ERROR).setMessage("失敗: " + ex.getMessage()).open();
}
}
}
});
btnSave.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
try {
String file = currentFile;
if (file.isEmpty()) {
FileDialog dlg = new FileDialog(shell, SWT.SAVE);
file = dlg.open();
if (file == null) return;
currentFile = file;
}
try (BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), "UTF-8"))) {
bw.write(text.getText());
}
shell.setText(file);
new MessageBox(shell, SWT.ICON_INFORMATION).setMessage("保存成功").open();
} catch (Exception ex) {
new MessageBox(shell, SWT.ICON_ERROR).setMessage("失敗: " + ex.getMessage()).open();
}
}
});
// 事件循環
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
}
2. JFace 版核心邏輯 (繼承 ApplicationWindow)
public class FirstJFace extends ApplicationWindow {
private Text text;
private String currentFile = "";
public FirstJFace() {
super(null); // 無父 Shell
setBlockOnOpen(true); // 打開後阻塞直到關閉
}
@Override
protected Control createContents(Composite parent) {
Composite top = new Composite(parent, SWT.NONE);
top.setLayout(new RowLayout(SWT.HORIZONTAL));
Button btnNew = new Button(top, SWT.PUSH);
btnNew.setText("新建");
Button btnOpen = new Button(top, SWT.PUSH);
btnOpen.setText("打開");
Button btnSave = new Button(top, SWT.PUSH);
btnSave.setText("保存");
text = new Text(parent, SWT.MULTI | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
// 事件綁定 (同 SWT 邏輯,省略重複代碼)
// ...
return parent;
}
public static void main(String[] args) {
new FirstJFace().run(); // 內建事件循環
}
}
四、關鍵差異總結與選型建議
- 佈局管理:SWT 手動
setBounds 或佈局器 (GridLayout/FillLayout);JFace 同樣使用佈局器,但 ApplicationWindow 默認 GridLayout 更友好。
- 資源管理:兩者均需手動
dispose() 顏色、字體、圖片等 OS 資源;JFace ApplicationWindow 關閉時自動釋放 Shell 資源。
- 高級組件:強烈推薦 JFace 的
TableViewer/TreeViewer + LabelProvider/ContentProvider 模式,實現模型與視圖解耦,支援排序、過濾、編輯。
- 部署體積:SWT ~2MB (JAR+DLL);JFace 額外 ~3MB。可接受範圍內。
五、進階學習路線圖
- 掌握 SWT 基礎控件、佈局、事件、繪圖 (GC)
- 學習 JFace Viewer 框架、Data Binding、Wizard/Dialog 框架
- 研究 Eclipse RCP 平台:Workbench、Extension Point、Commands/Handlers
- 實戰:開發一個基於 RCP 的多視圖桌面應用
官方資源:SWT 官網 | JFace 文檔 | 源碼倉庫
- 上一篇文章: Java 類文件加密保護實戰:基於自定義 ClassLoader 的即時解密方案
- 下一篇文章: Liferay 整合 TinyMCE 富文本編輯器:從中文化到圖片上傳完整落地指南
Copyright ©
程式碼之家 All Rights Reserved