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

Eclipse 3.0 SWT 程式設計實戰:打造原生效能的跨平台桌面應用

     編輯:Java 相關知識

SWT:Java 桌面開發的破局者

長期以來,AWT/Swing 的異質外觀、高資源消耗、執行效能差,讓 Java 桌面應用難獲用戶青睞。Standard Widget Toolkit (SWT) 由 Eclipse 專案組開發,最大化利用作業系統原生圖形元件(透過 JNI 呼叫),僅在 OS 缺乏對應元件時自行模擬。結果:標準原生外觀、接近 C/C++ 效能、跨平台無縫移植。SWT API 穩定度高,版本升級通常僅需替換 swt.jar 與原生庫即可。

開發環境配置

  • 作業系統:Windows + Eclipse 3.0
  • 專案結構:
+ swt (專案根目錄)
  + bin (編譯輸出)
  + src (原始碼)
    + AddressBookUI.java
  + swt-awt-win32-3062.dll
  + swt-win32-3062.dll
  + javaw.exe.manifest
  (以上 DLL/Manifest 來自 eclipse/plugins/org.eclipse.swt.win32_3.0.1/os/win32/x86)
  • Build Path 加入 swt.jar

通訊錄應用完整實作

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;
import org.eclipse.swt.events.*;
import org.eclipse.swt.layout.*;

public class AddressBookUI {
    private Shell shell;
    private Text miscText, addrText, emailText, phoneText, lnameText, fnameText;
    private Button cancelButton, saveButton, nextButton, prevButton, editButton, deleteButton, newButton;

    public static void main(String[] args) {
        new AddressBookUI().open();
    }

    public void open() {
        Display display = new Display();
        shell = new Shell(display);
        shell.setSize(610, 477);
        shell.setText("Address Book");

        // 建立 7 個功能按鈕:New, Delete, Edit, Previous, Next, Save, Cancel
        createButton("New", 10, e -> { clearText(); setEditable(true); enableEditBtns(false); enableSaveBtns(true); });
        createButton("Delete", 85, e -> { clearText(); System.out.println("Delete"); });
        createButton("Edit", 160, e -> { setEditable(true); enableEditBtns(false); enableSaveBtns(true); });
        createButton("Previous", 265, e -> System.out.println("Previous"));
        createButton("Next", 340, e -> System.out.println("Next"));
        saveButton = createButton("Save", 445, e -> { setEditable(false); enableEditBtns(true); enableSaveBtns(false); });
        saveButton.setEnabled(false);
        cancelButton = createButton("Cancel", 520, e -> { setEditable(false); enableEditBtns(true); enableSaveBtns(false); });
        cancelButton.setEnabled(false);

        // 建立詳細資料群組
        Group group = new Group(shell, SWT.NONE);
        group.setText("Details");
        group.setBounds(10, 10, 585, 355);

        String[] labels = {"First Name:", "Last Name:", "Phone:", "Email:", "Address:", "Miscellaneous Information:"};
        int[] yPos = {20, 60, 100, 140, 180, 255};
        Text[] fields = {fnameText, lnameText, phoneText, emailText, addrText, miscText};
        int[] styles = {SWT.BORDER | SWT.READ_ONLY, SWT.BORDER | SWT.READ_ONLY, 
                        SWT.BORDER | SWT.READ_ONLY, SWT.BORDER | SWT.READ_ONLY,
                        SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL,
                        SWT.BORDER | SWT.READ_ONLY | SWT.V_SCROLL};

        for (int i = 0; i < labels.length; i++) {
            new Label(group, SWT.NONE).setBounds(10, yPos[i], 135, 25).setText(labels[i]);
            fields[i] = new Text(group, styles[i]);
            fields[i].setBounds(150, yPos[i] - 5, 420, i >= 4 ? 60 : 25);
        }
        // 實際需將 fields 陣列元素賦值給對應欄位變數

        setupMenu();
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
        display.dispose();
    }

    private Button createButton(String text, int x, SelectionListener listener) {
        Button btn = new Button(shell, SWT.NONE);
        btn.setBounds(x, 380, 75, 35);
        btn.setText(text);
        btn.addSelectionListener(listener);
        return btn;
    }

    private void setupMenu() {
        Menu menuBar = new Menu(shell, SWT.BAR);
        shell.setMenuBar(menuBar);
        MenuItem file = new MenuItem(menuBar, SWT.CASCADE);
        file.setText("File");
        Menu fileMenu = new Menu(file);
        file.setMenu(fileMenu);

        createMenuItem(fileMenu, "Previous", SWT.NONE, e -> System.out.println("Previous"));
        createMenuItem(fileMenu, "Next", SWT.PUSH, e -> System.out.println("Next"));
        new MenuItem(fileMenu, SWT.SEPARATOR);
        createMenuItem(fileMenu, "Quit", SWT.PUSH, e -> shell.dispose());
    }

    private void createMenuItem(Menu parent, String text, int style, Listener listener) {
        MenuItem item = new MenuItem(parent, style);
        item.setText(text);
        item.addListener(SWT.Selection, listener);
    }

    private void clearText() { /* 清空所有 Text 欄位 */ }
    private void setEditable(boolean b) { /* 設定所有 Text editable 狀態 */ }
    private void enableEditBtns(boolean b) { newButton.setEnabled(b); deleteButton.setEnabled(b); editButton.setEnabled(b); }
    private void enableSaveBtns(boolean b) { saveButton.setEnabled(b); cancelButton.setEnabled(b); }
}

關鍵技術點解析

  • Display 事件迴路:readAndDispatch()/sleep() 是 SWT 應用的心跳,處理原生事件佇列
  • 原生元件綁定:Button、Text、Label 等直接對應 OS Widget,無 Swing 的輕量級繪製開銷
  • 座標佈局:採用 setBounds(x, y, w, h) 絕對定位,簡單直接;複雜介面可改用 GridLayout、FormLayout
  • 資源管理:Color、Font、Image 等圖形資源需手動 dispose(),避免 OS 句柄洩漏
  • 跨平台原生庫:部署時必須隨應用打包對應平台的 swt-*.dll/.so 並設定 java.library.path

執行與驗證

專案設定完成後,直接 Run As Java Application 即可啟動通訊錄視窗。按鈕點擊、選單操作、欄位編輯狀態切換皆在 Console 輸出對應日誌,驗證事件綁定正確性。

進階發展方向

  1. 整合 JFace:提供 Viewer、Data Binding、Wizard、Dialog 等高階 UI 框架
  2. 資料持久化:結合 JDBC/Hibernate 實現真實通訊錄 CRUD
  3. 國際化:外部化字串資源,支援多語系
  4. 打包部署:使用 Eclipse Product Export 或打包為可執行 JAR + 原生啟動器
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved