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

SWT/JFace 選單與工具列完整實作:Menu、CoolBar、ToolBar 深度解析

     編輯:Java 相關知識

前言

選單列、工具列、酷工具列是桌面應用的核心導航元件。SWT 提供 Menu、ToolBar、CoolBar 三大類別,JFace 進一步封裝 MenuManager、ToolBarManager、CoolBarManager 簡化動作管理。本文透過三個完整範例,詳細解析各元件的建立、事件處理、圖示設定、快捷鍵、下拉選單、狀態持久化等實務技巧。

一、Menu:選單列與彈出選單

基本結構

Menu menuBar = new Menu(shell, SWT.BAR); // 選單列
shell.setMenuBar(menuBar);

MenuItem fileItem = new MenuItem(menuBar, SWT.CASCADE);
fileItem.setText("&File");
Menu fileMenu = new Menu(shell, SWT.DROP_DOWN);
fileItem.setMenu(fileMenu);

MenuItem newItem = new MenuItem(fileMenu, SWT.PUSH);
newItem.setText("&New\tCtrl+N");
newItem.setAccelerator(SWT.CTRL | 'N');
newItem.addListener(SWT.Selection, e -> System.out.println("New"));

關鍵元件類型

Style用途範例
SWT.CASCADE包含子選單的項目File、Edit 等主選單
SWT.PUSH一般命令項目New、Open、Save
SWT.CHECK可切換狀態(打勾)顯示行號、自動換行
SWT.RADIO單選群組(同組互斥)語言選擇、主題切換
SWT.SEPARATOR分隔線群組分隔

圖示、快捷鍵、加速鍵

Image icon = new Image(display, "icons/new.gif");
newItem.setImage(icon);
newItem.setAccelerator(SWT.CTRL | 'N'); // 真正觸發快捷鍵
newItem.setText("&New\tCtrl+N"); // 顯示用快捷鍵提示

setAccelerator 才是真正註冊鍵盤快捷鍵;\t 後的文字僅為顯示提示。

下拉選單按鈕

ToolItem dropDown = new ToolItem(toolBar, SWT.DROP_DOWN);
dropDown.setText("Options");
Menu popup = new Menu(shell, SWT.POP_UP);
new MenuItem(popup, SWT.PUSH).setText("Item 1");
new MenuItem(popup, SWT.PUSH).setText("Item 2");

dropDown.addListener(SWT.Selection, e -> {
    if (e.detail == SWT.ARROW) { // 僅點擊箭頭區域
        Rectangle bounds = dropDown.getBounds();
        Point pt = toolBar.toDisplay(bounds.x, bounds.y + bounds.height);
        popup.setLocation(pt);
        popup.setVisible(true);
    }
});

二、ToolBar:標準工具列

建立與佈局

ToolBar toolBar = new ToolBar(shell, SWT.FLAT | SWT.WRAP | SWT.RIGHT);
toolBar.pack(); // 依元件建議尺寸調整
shell.addListener(SWT.Resize, e -> {
    Rectangle area = shell.getClientArea();
    toolBar.setSize(toolBar.computeSize(area.width, SWT.DEFAULT));
});
  • SWT.FLAT:扁平風格(現代外觀)
  • SWT.WRAP:空間不足時自動換行
  • SWT.RIGHT:靠右對齊

ToolItem 類型與控制項嵌入

// 一般按鈕
ToolItem push = new ToolItem(toolBar, SWT.PUSH);
push.setText("Push"); push.setImage(icon);

// 核取方塊/單選按鈕
ToolItem check = new ToolItem(toolBar, SWT.CHECK);
ToolItem radio1 = new ToolItem(toolBar, SWT.RADIO);
ToolItem radio2 = new ToolItem(toolBar, SWT.RADIO); // 同組自動互斥

// 分隔器可嵌入控制項
ToolItem sep = new ToolItem(toolBar, SWT.SEPARATOR);
Text text = new Text(toolBar, SWT.BORDER | SWT.SINGLE);
text.pack();
sep.setWidth(text.getBounds().width);
sep.setControl(text); // 文字框嵌入工具列

統一事件處理

Listener listener = e -> {
    ToolItem item = (ToolItem) e.widget;
    System.out.println(item.getText() + " selected");
    if ((item.getStyle() & SWT.CHECK) != 0 || (item.getStyle() & SWT.RADIO) != 0)
        System.out.println("State: " + item.getSelection());
};
push.addListener(SWT.Selection, listener);
check.addListener(SWT.Selection, listener);
radio1.addListener(SWT.Selection, listener);
radio2.addListener(SWT.Selection, listener);

三、CoolBar:可調整佈局的酷工具列

特色

  • 支援拖曳重新排序 CoolItem
  • 支援換行(Wrap)與尺寸調整
  • 可持久化佈局狀態(順序、換行位置、尺寸)

建立與項目加入

CoolBar coolBar = new CoolBar(shell, SWT.NONE);
coolBar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

// 文字輸入項
CoolItem textItem = new CoolItem(coolBar, SWT.NONE);
Text text = new Text(coolBar, SWT.BORDER | SWT.DROP_DOWN);
text.setText("TEXT");
text.pack();
textItem.setControl(text);
textItem.setSize(textItem.computeSize(text.getSize().x, text.getSize().y));

// 標籤項
CoolItem labelItem = new CoolItem(coolBar, SWT.NONE);
Label label = new Label(coolBar, SWT.NONE);
label.setText("LABEL");
label.pack();
labelItem.setControl(label);
labelItem.setSize(labelItem.computeSize(label.getSize().x, label.getSize().y));

// 複合控制項項(按鈕群組)
CoolItem btnItem = new CoolItem(coolBar, SWT.NONE | SWT.DROP_DOWN);
Composite comp = new Composite(coolBar, SWT.NONE);
comp.setLayout(new GridLayout(2, true));
new Button(comp, SWT.PUSH).setText("Button 1");
new Button(comp, SWT.PUSH).setText("Button 2");
comp.pack();
btnItem.setControl(comp);
btnItem.setSize(btnItem.computeSize(comp.getSize().x, comp.getSize().y));

狀態持久化(儲存/載入佈局)

// 儲存
void saveState(CoolBar bar, File file) throws IOException {
    DataOutputStream out = new DataOutputStream(new FileOutputStream(file));
    try {
        int[] order = bar.getItemOrder();
        out.writeInt(order.length);
        for (int i : order) out.writeInt(i);
        
        int[] wraps = bar.getWrapIndices();
        out.writeInt(wraps.length);
        for (int i : wraps) out.writeInt(i);
        
        Point[] sizes = bar.getItemSizes();
        out.writeInt(sizes.length);
        for (Point p : sizes) { out.writeInt(p.x); out.writeInt(p.y); }
    } finally { out.close(); }
}

// 載入
void setState(CoolBar bar, File file) throws IOException {
    DataInputStream in = new DataInputStream(new FileInputStream(file));
    try {
        int[] order = new int[in.readInt()];
        for (int i = 0; i < order.length; i++) order[i] = in.readInt();
        int[] wraps = new int[in.readInt()];
        for (int i = 0; i < wraps.length; i++) wraps[i] = in.readInt();
        Point[] sizes = new Point[in.readInt()];
        for (int i = 0; i < sizes.length; i++) sizes[i] = new Point(in.readInt(), in.readInt());
        bar.setItemLayout(order, wraps, sizes);
    } finally { in.close(); }
}

// 視窗關閉時自動儲存
shell.addListener(SWT.Close, e -> {
    try { saveState(coolBar, new File("coolbar.state")); }
    catch (IOException ex) { ex.printStackTrace(); }
});

JFace 封裝優勢

實際專案建議使用 JFace 的 MenuManager、ToolBarManager、CoolBarManager 搭配 Action / IAction:

  • 動作邏輯與 UI 分離,可同時貢獻至選單、工具列、右鍵選單
  • 自動處理啟用/停用、勾選狀態、圖示、快捷鍵同步
  • 支援 IContributionItem 動態貢獻、Expression 可見性控制

總結

Menu、ToolBar、CoolBar 是 SWT 應用導航的三大支柱。掌握其核心 API、事件模型、佈局特性與持久化技巧,並善用 JFace 封裝提升可維護性,即可打造出專業級的桌面應用介面。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved