SWT 中還有一些常用組件,能使介面更具表現力,稱為展現組件,在 SWT 開發中不可或缺,包括選單組件、工具列組件 ToolBar 與 ToolItem、工具列組件 CoolBar 與 CoolItem、滑桿組件 Slider、刻度組件 Scale 與進度條組件 ProgressBar 等。
程式中選單是提供資訊較好方式。SWT 透過 Menu 與 MenuItem 實作選單與選單項。新增選單步驟:
Menu 物件,指定樣式,如 menuBar = new Menu(shell, SWT.BAR);MenuItem 物件,指定樣式,如 fileEnglishItem = new MenuItem(fileMenu, SWT.RADIO);Menu 與 MenuItem 關聯(Menu 中可含子 Menu),如 fileMenuHeader.setMenu(fileMenu);MenuItem 事件監聽器,如 fileEnglishItem.addSelectionListener(new RadioItemListener());為更好掌握選單,以下實例示範建立選單,代碼如範例 1:
public class MenuExample {
Display display; Shell shell;
Menu menuBar, fileMenu, editMenu;
MenuItem fileMenuHeader, editMenuHeader;
MenuItem fileExitItem, fileSaveItem, fileEnglishItem, fileGermanItem, editCopyItem;
Text text;
public MenuExample() {
display = new Display();
shell = new Shell(display);
shell.setText("Menu Example");
shell.setSize(300, 200);
text = new Text(shell, SWT.BORDER);
text.setBounds(80, 50, 150, 25);
// 新增主選單項
menuBar = new Menu(shell, SWT.BAR);
// 新增一級子選單
fileMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
fileMenuHeader.setText("&File");
// 新增一級子選單的選單項
fileMenu = new Menu(shell, SWT.DROP_DOWN);
fileMenuHeader.setMenu(fileMenu);
fileSaveItem = new MenuItem(fileMenu, SWT.PUSH);
fileSaveItem.setText("&Save");
fileEnglishItem = new MenuItem(fileMenu, SWT.RADIO);
fileEnglishItem.setText("English");
fileGermanItem = new MenuItem(fileMenu, SWT.RADIO);
fileGermanItem.setText("German");
fileExitItem = new MenuItem(fileMenu, SWT.PUSH);
fileExitItem.setText("E&xit");
editMenuHeader = new MenuItem(menuBar, SWT.CASCADE);
editMenuHeader.setText("&Edit");
editMenu = new Menu(shell, SWT.DROP_DOWN);
editMenuHeader.setMenu(editMenu);
editCopyItem = new MenuItem(editMenu, SWT.PUSH);
editCopyItem.setText("&Copy");
// 新增選單項事件監聽器
fileExitItem.addSelectionListener(new MenuItemListener());
fileSaveItem.addSelectionListener(new MenuItemListener());
editCopyItem.addSelectionListener(new MenuItemListener());
fileEnglishItem.addSelectionListener(new RadioItemListener());
fileGermanItem.addSelectionListener(new RadioItemListener());
shell.setMenuBar(menuBar);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
class MenuItemListener extends SelectionAdapter {
public void widgetSelected(SelectionEvent event) {
text.setText("You selected " + ((MenuItem) event.widget).getText());
if (((MenuItem) event.widget).getText().equals("E&xit")) shell.close();
}
}
class RadioItemListener extends SelectionAdapter {
public void widgetSelected(SelectionEvent event) {
MenuItem item = (MenuItem) event.widget;
text.setText(item.getText() + " is on.");
}
}
public static void main(String[] args) { new MenuExample(); }
}
程式新增主選單,主選單中加兩個子選單項,子選單項加相應事件回應機制。執行效果如圖 1:

選單可級聯,子選單中仍可包含其他選單項。
ToolBar 為 SWT 工具列組件,ToolItem 為工具列中的工具項(通常表現為按鈕或分隔符,也可為其他組件)。新增工具列步驟:
ToolBar 物件,指定樣式,如 toolBar = new ToolBar(shell, SWT.FLAT | SWT.WRAP | SWT.RIGHT);ToolItem 物件,指定樣式,如 ToolItem itemPush = new ToolItem(toolBar, SWT.PUSH);ToolItem 圖示與相關屬性,如 itemPush.setImage(icon);ToolItem 事件監聽器,如 itemPush.addListener(SWT.Selection, selectionListener);範例 2 示範建立工具列組件:
public class ToolBarExample {
Display display = new Display();
Shell shell = new Shell(display);
ToolBar toolBar;
public ToolBarExample() {
toolBar = new ToolBar(shell, SWT.FLAT | SWT.WRAP | SWT.RIGHT);
ToolItem itemPush = new ToolItem(toolBar, SWT.PUSH);
itemPush.setText("PUSH item");
ToolItem itemCheck = new ToolItem(toolBar, SWT.CHECK);
itemCheck.setText("CHECK item");
ToolItem itemRadio1 = new ToolItem(toolBar, SWT.RADIO);
itemRadio1.setText("RADIO item 1");
ToolItem itemRadio2 = new ToolItem(toolBar, SWT.RADIO);
itemRadio2.setText("RADIO item 2");
ToolItem itemSeparator = new ToolItem(toolBar, SWT.SEPARATOR);
final ToolItem itemDropDown = new ToolItem(toolBar, SWT.DROP_DOWN);
itemDropDown.setText("DROP_DOWN item");
itemDropDown.setToolTipText("Click here to see a drop down menu ...");
final Menu menu = new Menu(shell, SWT.POP_UP);
new MenuItem(menu, SWT.PUSH).setText("Menu item 1");
new MenuItem(menu, SWT.PUSH).setText("Menu item 2");
new MenuItem(menu, SWT.SEPARATOR);
new MenuItem(menu, SWT.PUSH).setText("Menu item 3");
itemDropDown.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
if (event.detail == SWT.ARROW) {
Rectangle bounds = itemDropDown.getBounds();
Point point = toolBar.toDisplay(bounds.x, bounds.y + bounds.height);
menu.setLocation(point);
menu.setVisible(true);
}
}
});
Listener selectionListener = new Listener() {
public void handleEvent(Event event) {
ToolItem item = (ToolItem) event.widget;
System.out.println(item.getText() + " is selected");
if ((item.getStyle() & SWT.RADIO) != 0 || (item.getStyle() & SWT.CHECK) != 0)
System.out.println("Selection status: " + item.getSelection());
}
};
itemPush.addListener(SWT.Selection, selectionListener);
itemCheck.addListener(SWT.Selection, selectionListener);
itemRadio1.addListener(SWT.Selection, selectionListener);
itemRadio2.addListener(SWT.Selection, selectionListener);
itemDropDown.addListener(SWT.Selection, selectionListener);
toolBar.pack();
shell.addListener(SWT.Resize, new Listener() {
public void handleEvent(Event event) {
Rectangle clientArea = shell.getClientArea();
toolBar.setSize(toolBar.computeSize(clientArea.width, SWT.DEFAULT));
}
});
shell.setSize(400, 100);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) { new ToolBarExample(); }
}
程式新增工具列與工具項,工具項加事件回應,工具列與選單配合,選單動態設定顯示位置。執行效果如圖 2:

CoolBar 為另一形式工具列,能調整 CoolItem 位置,每個 CoolItem 可設定相關組件(也可為另一工具列)。建立步驟:
CoolBar 物件,指定樣式,如 CoolBar composite = new CoolBar(parent, SWT.NONE);CoolItem 物件,指定樣式,如 CoolItem item = new CoolItem(composite, SWT.NONE);CoolItem 的 Control 物件,如 item.setControl(tb);CoolBar 相當面板容器,CoolItem 為容器中每一項,可設定相應組件作為子容器。範例 3 示範:
public class CoolBarExample extends ApplicationWindow {
public CoolBarExample() { super(null); }
protected Control createContents(Composite parent) {
getShell().setText("CoolBar Test");
String asCoolItemSection[] = { "File", "Formatting", "Search" };
CoolBar composite = new CoolBar(parent, SWT.NONE);
for (int idxCoolItem = 0; idxCoolItem < 3; ++idxCoolItem) {
CoolItem item = new CoolItem(composite, SWT.NONE);
ToolBar tb = new ToolBar(composite, SWT.FLAT);
for (int idxItem = 0; idxItem < 3; ++idxItem) {
ToolItem ti = new ToolItem(tb, SWT.NONE);
ti.setText(asCoolItemSection[idxCoolItem] + " Item #" + idxItem);
}
Point p = tb.computeSize(SWT.DEFAULT, SWT.DEFAULT);
tb.setSize(p);
Point p2 = item.computeSize(p.x, p.y);
item.setControl(tb);
item.setSize(p2);
}
return composite;
}
public static void main(String[] args) {
CoolBarExample app = new CoolBarExample();
app.setBlockOnOpen(true);
app.open();
Display.getCurrent().dispose();
}
}
代碼示範建立 CoolBar,每個 CoolItem 可依使用者需求調整位置。執行效果如圖 3:

CoolBar 與 ToolBar 展現樣式不同,CoolBar 可動態調整工具列位置。
為方便使用者輸入資料,SWT 提供 Slider 組件,使用者可透過 Slider 設定資料增量值控制其他組件,或作為捲軸控制其他組件資料顯示。新增步驟:
Slider 物件,指定樣式,如 Slider slide = new Slider(shell, SWT.HORIZONTAL);slide.setMaximum(100);slide.setIncrement(1);slide.addSelectionListener(selectionListener);範例 4 示範:
public class SliderExample {
Display dispaly; Shell shell;
SliderExample() {
dispaly = new Display(); shell = new Shell(dispaly);
shell.setSize(300, 250); shell.setText("A Slider Example");
final Slider slide = new Slider(shell, SWT.V_SCROLL);
slide.setBounds(170, 25, 25, 20);
slide.setMinimum(0); slide.setMaximum(100); slide.setIncrement(1);
final Text t = new Text(shell, SWT.BORDER);
t.setBounds(115, 25, 55, 20); t.setText("0"); t.setFocus();
slide.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
t.setText(new Integer(slide.getSelection()).toString());
}
});
shell.open();
while (!shell.isDisposed()) {
if (!dispaly.readAndDispatch()) dispaly.sleep();
}
dispaly.dispose();
}
public static void main(String[] args) { new SliderExample(); }
}
新增 Text 與 Slider 組件,Slider 設定增量 1,選擇事件選擇 Slider 後為 Text 賦值。執行效果如圖 4:

Slider 組件需配合其他組件使用,輔助完成功能。
Scale 與 Slider 類似,在 SWT 均表示一種尺度,但表現形式不同:Scale 更像刻度,Slider 提供捲軸。新增步驟:
Scale 物件,指定樣式,如 Scale scale = new Scale(shell, SWT.VERTICAL);scale.setMaximum(20);scale.setPageIncrement(5);scale.addSelectionListener(selectionListener);範例 5 示範:
public class ScaleExample {
Display display = new Display(); Shell shell = new Shell(display);
Scale scale; Text value;
public ScaleExample() {
shell.setLayout(new GridLayout(1, true));
Label label = new Label(shell, SWT.NULL); label.setText("Volume:");
scale = new Scale(shell, SWT.VERTICAL);
scale.setBounds(0, 0, 40, 200);
scale.setMaximum(20); scale.setMinimum(0); scale.setPageIncrement(5);
scale.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
int perspectiveValue = scale.getMaximum() - scale.getSelection() + scale.getMinimum();
value.setText("Vol: " + perspectiveValue);
}
});
value = new Text(shell, SWT.BORDER | SWT.SINGLE);
value.setEditable(false);
scale.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
value.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_CENTER));
shell.pack(); shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) { new ScaleExample(); }
}
透過事件監聽器監聽當前選擇刻度,用 Text 組件顯示。執行效果如圖 5:

Scale 組件能精確顯示刻度,使用者可設定刻度範圍,非常有用。
ProgressBar 為 SWT 進度條組件,提供較長時間操作進度資訊。新增步驟:
ProgressBar 物件,指定樣式,如 ProgressBar pb1 = new ProgressBar(shell, SWT.HORIZONTAL | SWT.SMOOTH);pb1.setMaximum(30);progressBar.setSelection(progressBar.getSelection() + 1);進度條常配合執行緒使用,避免阻塞影響介面操作。範例 6 示範:
public class ProgressBarExample {
public static void main(String[] args) {
Display display = new Display(); Shell shell = new Shell(display);
shell.setLayout(new GridLayout());
ProgressBar pb1 = new ProgressBar(shell, SWT.HORIZONTAL | SWT.SMOOTH);
pb1.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
pb1.setMinimum(0); pb1.setMaximum(30);
ProgressBar pb2 = new ProgressBar(shell, SWT.HORIZONTAL | SWT.INDETERMINATE);
pb2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
new LongRunningOperation(display, pb1).start();
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) display.sleep();
}
}
}
class LongRunningOperation extends Thread {
private Display display; private ProgressBar progressBar;
public LongRunningOperation(Display display, ProgressBar progressBar) {
this.display = display; this.progressBar = progressBar;
}
public void run() {
for (int i = 0; i < 30; i++) {
try { Thread.sleep(1000); } catch (InterruptedException e) {}
display.asyncExec(new Runnable() {
public void run() {
if (progressBar.isDisposed()) return;
progressBar.setSelection(progressBar.getSelection() + 1);
}
});
}
}
}
新增兩進度條:一自動顯示增加進度(SWT.INDETERMINATE 樣式),另一透過執行緒處理長時間任務設定進度。執行效果如圖 6:

進度條有不同樣式,開發人員可控制進度,執行長時間操作。