首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

SWT/JFace 入門實戰:從原理到記事本Demo全解析

     編輯:Java 程式設計入門

為什麼選擇 SWT/JFace?

Java GUI 三大陣營:AWT (重量級、外觀隨平台)、Swing (輕量級、可換膚、性能一般)、SWT (IBM Eclipse 核心,**底層 JNI 直呼系統 API**,原生外觀、高性能、豐富控件)。JFace 是 SWT 之上的面向對象封裝層(類比 MFC 封裝 Win32 API),提供 Viewer、DataBinding、Wizard、Dialog 等高級組件,大幅提升開發效率。

一、環境搭建:必備文件清單

SWT (Windows x86_64 示例)

  • swt.jar
  • 4 個原生庫:swt-win32-XXXX.dll, swt-gdip-win32-XXXX.dll, swt-awt-win32-XXXX.dll, swt-wgl-win32-XXXX.dll

部署時:DLL 放入 PATH 或 -Djava.library.path=./lib;JAR 放入 Class-Path 或 -cp。

JFace 額外 5 個 JAR (從 Eclipse plugins 目錄獲取)

  • org.eclipse.core.runtime_3.x.x.jar
  • org.eclipse.jface_3.x.x.jar
  • org.eclipse.jface.text_3.x.x.jar
  • org.eclipse.osgi_3.x.x.jar
  • org.eclipse.text_3.x.x.jar

版本號需與目標 Eclipse 版本一致。

二、核心架構對比:SWT vs JFace

三、實戰:雙版本「記事本」完整代碼走讀

功能:工具欄「新建/打開/保存」+ 多行文本編輯區。

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。可接受範圍內。

五、進階學習路線圖

  1. 掌握 SWT 基礎控件、佈局、事件、繪圖 (GC)
  2. 學習 JFace Viewer 框架、Data Binding、Wizard/Dialog 框架
  3. 研究 Eclipse RCP 平台:Workbench、Extension Point、Commands/Handlers
  4. 實戰:開發一個基於 RCP 的多視圖桌面應用

官方資源:SWT 官網 | JFace 文檔 | 源碼倉庫

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
維度SWTJFace
窗口基類Shell (需自建 Display)ApplicationWindow (內建生命週期)
控件創建直接 new Button(shell, SWT.PUSH)在 createContents(Composite parent) 回調中創建
事件處理addSelectionListener(new SelectionAdapter(){...})同 SWT,但常結合 Viewer 使用
事件循環手寫 while(!shell.isDisposed()){...}ApplicationWindow.run() 內建
適用場景精細控制、非標準窗口、輕量部署標準應用窗口、需快速構建、數據綁定