本文介紹菜單系統、列表輸入控件(Combo、List)、進階顯示控件(Table、Tree)、佈局管理器FormLayout,並構建可復用的BasicApplication基類。
菜單提升GUI可用性。Menu樣式互斥:BAR(菜單欄)、DROP_DOWN(下拉)、POP_UP(彈出)。可選NO_RADIO_GROUP、LEFT_TO_RIGHT/RIGHT_TO_LEFT。MenuItem五種互斥樣式:CHECK、CASCADE(含子菜單)、PUSH、RADIO、SEPARATOR。支持加速鍵(Ctrl+字母)與助記符(&標記字母)。清單1構建含「文件/幫助」菜單欄與彈出菜單的系統(圖1-4)。清單2封裝創建輔助方法,清單3利用Java反射將菜單項回調映射到應用類公共方法(如doExit)。
protected Menu createMenu(Shell parent, int style, MenuItem container, boolean enabled) {
Menu m = createMenu(parent, style);
m.setEnabled(enabled);
container.setMenu(m);
return m;
}
protected MenuItem createMenuItem(Menu parent, int style, String text,
Image icon, int accel, boolean enabled, String callback) {
MenuItem mi = new MenuItem(parent, style);
if (text != null) mi.setText(text);
if (icon != null) mi.setImage(icon);
if (accel != -1) mi.setAccelerator(accel);
mi.setEnabled(enabled);
if (callback != null) registerCallback(mi, this, callback);
return mi;
}
清單 2. 菜單創建輔助例程

圖 1. 帶有 File 和 Help 菜單的菜單欄

圖 2. 下拉狀態的 File 菜單

圖 3. 下拉狀態的 Help 菜單

圖 4. 彈出菜單
兩者均從預定值選擇,List佔空間大,Combo可下拉節省空間。Combo樣式互斥:SIMPLE、DROP_DOWN;可選READ_ONLY。兩者均支持SINGLE/MULTI選擇、H_SCROLL/V_SCROLL。清單4使用FormLayout創建示例(圖5)。CCombo(custom包)為替代實現,支持程序化剪切/複製/貼上,固定DROP_DOWN樣式,額外支持BORDER、READ_ONLY。
protected Combo createCombo(Composite parent, String[] data) {
Combo combo = new Combo(parent, SWT.DROP_DOWN | SWT.MULTI | SWT.V_SCROLL | SWT.H_SCROLL);
combo.addSelectionListener(...);
setComboContents(data);
return combo;
}

圖 5. 組合框和列表的例子
FormLayout允許控件相對其他控件或容器邊緣定位(左/上/右/下),未附著邊採用自然尺寸。FormAttachment指定百分比與像素偏移。清單5封裝configureLayout輔助方法。
Table增強List,支持TableColumn對齊數據、列標題、可調寬度。可選樣式:CHECK(首列複選框)、VIRTUAL(大數據)、FULL_SELECTION(整行選中)。清單6創建含三列、複選框的表(圖6)。
protected Table createTable(Composite parent, int mode, Object[] contents) {
table = new Table(parent, mode | SWT.SINGLE | SWT.FULL_SELECTION | SWT.V_SCROLL | SWT.H_SCROLL);
table.setHeaderVisible(true);
table.setLinesVisible(true);
createTableColumn(table, SWT.LEFT, "Column 1", 100);
// ...
addTableContents(contents);
return table;
}

圖 6. 表的例子
Tree顯示分層數據,支持展開/摺疊。需數據模型(此處用內部類Node,清單7)。清單8遞歸構建樹(圖7),可選首列複選框。
public class Node {
protected List children;
protected String name;
// getter/setter/addChild...
}

圖 7. 樹的例子
封裝通用功能:創建Shell、退出確認對話框(圖8)、控件樹診斷輸出(清單9)。子類需實現構造器、completeGui、可選initGui(清單11)。main方法通過反射啟動(清單10)。

圖 8. 確認消息對話框
MessageBox樣式互斥:ICON_ERROR、ICON_INFORMATION、ICON_QUESTION、ICON_WARNING、ICON_WORKING;按鈕組合:OK、OK|CANCEL、YES|NO、YES|NO|CANCEL、RETRY|CANCEL、ABORT|RETRY|IGNORE。清單12實現關閉確認(圖8)。
shell.addShellListener(new ShellAdapter() {
public void shellClosed(ShellEvent e) {
MessageBox mb = new MessageBox(shell, SWT.ICON_QUESTION | SWT.OK | SWT.CANCEL);
mb.setText("Confirm Exit");
mb.setMessage("Are you sure you want to exit?");
int rc = mb.open();
e.doit = rc == SWT.OK;
}
});
清單 12. 使用 MessageBox 創建退出確認對話框
本文覆蓋菜單、Combo/List、Table/Tree、FormLayout、基礎架構與MessageBox。下期將介紹更多容器、輸入控件與StackLayout。
來源:IBM developerWorks