使用 Eclipse SWT(Standard Widget Toolkit)開發原生風格桌面記事本,實現文件操作、編輯、格式、查看、幫助五大菜單功能,包含新建、打開、保存、另存為、撤銷、剪切、複製、粘貼、查找、替換、轉到、字體設置、自動換行、狀態欄、時間戳插入等核心功能。
NotePadcom.chance.orgNotePad(主窗口)、Util(工具類)、AboutAuthor、FindWindow、GoToWindow、OpenMethod、SaveMethod、QuitMethod、SWTResourceManager、Main(入口)// 主 Shell
Shell shell = new Shell(display, SWT.SHELL_TRIM | SWT.MAX | SWT.MIN);
shell.setText("無標題 - 記事本");
shell.setLayout(new FillLayout());
// 菜單欄
Menu menuBar = new Menu(shell, SWT.BAR);
shell.setMenuBar(menuBar);
// 文件菜單
MenuItem fileMenu = new MenuItem(menuBar, SWT.CASCADE);
fileMenu.setText("文件(&F)");
Menu fileSub = new Menu(shell, SWT.DROP_DOWN);
fileMenu.setMenu(fileSub);
// 子項:新建、打開、保存、另存為、退出
createMenuItem(fileSub, "新建(&N)\tCtrl+N", SWT.CTRL | 'N', e -> doNew());
createMenuItem(fileSub, "打開(&O)\tCtrl+O", SWT.CTRL | 'O', e -> doOpen());
createMenuItem(fileSub, "保存(&S)\tCtrl+S", SWT.CTRL | 'S', e -> doSave());
createMenuItem(fileSub, "另存為(&A)", SWT.NONE, e -> doSaveAs());
createMenuItem(fileSub, "退出(&X)", SWT.NONE, e -> doQuit());
// 其他菜單同理...
Composite composite = new Composite(shell, SWT.NONE);
composite.setLayout(new FillLayout());
Text text = new Text(composite, SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL | SWT.WRAP);
text.setFont(new Font(display, "Consolas", 11, SWT.NORMAL));
統一管理 filePath 字段記錄當前文件路徑。操作前檢查內容是否修改(isDirty 標誌),提示保存。
private void doOpen() {
if (checkDirtyAndPrompt()) return;
FileDialog dialog = new FileDialog(shell, SWT.OPEN);
dialog.setFilterExtensions(new String[]{"*.txt", "*.java", "*.*"});
String path = dialog.open();
if (path != null) {
loadFile(path);
filePath = path;
shell.setText(new File(path).getName() + " - 記事本");
}
}
private void loadFile(String path) {
try (BufferedReader reader = new BufferedReader(new FileReader(path))) {
text.setText("");
String line;
while ((line = reader.readLine()) != null) {
text.append(line + "\n");
}
isDirty = false;
} catch (IOException ex) { showError("打開失敗: " + ex.getMessage()); }
}
直接委託 Text 原生方法:
text.cut(); text.copy(); text.paste(); text.selectAll();
// 撤銷需自行實現或使用 UndoManager(SWT 無內置,可集成第三方)
使用無模式對話框 (SWT.DIALOG_TRIM):
// FindWindow 核心邏輯
private void findNext() {
String content = text.getText();
String keyword = findText.getText();
int start = text.getCaretPosition();
int idx = content.indexOf(keyword, start);
if (idx >= 0) {
text.setSelection(idx, idx + keyword.length());
text.setFocus();
} else {
showMessage("未找到: " + keyword);
}
}
private void replace() {
String content = text.getText();
String newContent = content.replaceFirst(findText.getText(), replaceText.getText());
text.setText(newContent);
}
FontDialog fontDialog = new FontDialog(shell);
fontDialog.setFontList(text.getFont().getFontData());
FontData fd = fontDialog.open();
if (fd != null) {
Font newFont = new Font(display, fd);
text.setFont(newFont);
// 釋放舊字體
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String now = sdf.format(new Date());
int caret = text.getCaretPosition();
String before = text.getText(0, caret);
String after = text.getText(caret, text.getCharCount() - caret);
text.setText(before + now + after);
單例持有主窗口引用,便於各對話框訪問主窗口組件:
public class Util {
public static NotePad shell;
public static Text getText() { return shell.text; }
public static String getFilePath() { return shell.filePath; }
public static void setFilePath(String p) { shell.filePath = p; }
}
swt.jar(平台相關),或使用 maven-shade-plugin 構建 Fat JAR| 問題 | 解決方案 |
|---|---|
| 中文顯示方框 | 設置字體支持中文:new Font(display, "Microsoft YaHei", 12, SWT.NORMAL) |
| 大文件打開卡頓 | 使用 FileChannel + 內存映射 或 分頁加載 |
| 圖標不顯示 | shell.setImage(new Image(display, "icon.ico")) 路徑正確 |
| 退出確認邏輯複雜 | 統一 checkDirtyAndPrompt() 返回 boolean,true 表示用戶取消操作 |
SWT 直接調用系統原生控件,界面原生、性能優異、體積輕量。本項目展示了菜單構建、文件 IO、對話框交互、文本操作、事件處理等桌面開發核心技能。進階方向:插件化架構、語法高亮、多標籤頁、自動保存、雲同步。