【IT168 技术文章】
简介
BarApp 是 BasicApplication 类(内含控件生成方法)的扩展。还使用了这个应用程序的几幅屏幕快照来展示不同控件的特性。
图 1 显示所有控件,包括几个 ToolBar 和一个 CoolBar。最左边是三个有边框的 Composite(包含一个 Label),每个 Composite 都位于一个 SashForm 面板内。而 SashForm 本身又处在一个更大的 SashForm 中有边框的 Composite 内。靠近左侧中间是一个垂直的 ToolBar,它的顶部有一个 Open Tracker 按钮。在右上方是四个水平的 ToolBar(在两个 CBanner 中)—— 但只能看到两个;前两个使用了文本标签,后两个使用图片(同一张图片)。这几个 ToolBar 和 CBanner 全都在外围 SashForm 中的一个 Composite 中。从清单 1 的控件层次结构中可以清楚地看出这个结构。
图 1. BarApp 示例
清单 1. BarApp 应用程序的控件层次结构
2 1: SashForm {}
3 2: Composite {}
4 3: SashForm {}
5 4: Composite {}
6 5: Label {Left Pane}
7 4: Composite {}
8 5: Label {Center Pane}
9 4: Composite {}
10 5: Label {Right Pane}
11 2: Composite {}
12 3: ToolBar {}
13 4: ToolItem {Open Tracker}
14 4: ToolItem {Check}
15 4: ToolItem {Drop}
16 4: ToolItem {}
17 4: ToolItem {Radio 1}
18 4: ToolItem {Radio 2}
19 4: ToolItem {Radio 3}
20 4: Label {}
21 3: CBanner {}
22 4: ToolBar {}
23 5: ToolItem {Press 1}
24 5: ToolItem {Check}
25 5: ToolItem {Drop}
26 5: ToolItem {}
27 5: ToolItem {Radio 1}
28 5: ToolItem {Radio 2}
29 5: ToolItem {Radio 3}
30 5: Label {}
31 4: ToolBar {}
32 5: ToolItem {Push 2}
33 5: ToolItem {Check}
34 5: ToolItem {Drop}
35 5: ToolItem {}
36 5: ToolItem {Radio 1}
37 5: ToolItem {Radio 2}
38 5: ToolItem {Radio 3}
39 5: Label {}
40 3: CBanner {}
41 4: ToolBar {}
42 5: ToolItem {}
43 5: ToolItem {}
44 5: ToolItem {}
45 5: ToolItem {}
46 5: ToolItem {}
47 5: ToolItem {}
48 5: ToolItem {}
49 5: Label {}
50 4: ToolBar {}
51 5: ToolItem {}
52 5: ToolItem {}
53 5: ToolItem {}
54 5: ToolItem {}
55 5: ToolItem {}
56 5: ToolItem {}
57 5: ToolItem {}
58 5: Label {}
59 3: CoolBar {}
60 4: CoolItem {Drop}
61 4: CoolItem {Drop}
62 4: CoolItem {Drop}
63 4: CoolItem {Drop}
64 4: CoolItem {Drop}
65 4: Button {Press Me 1}
66 4: Button {Press Me 2}
67 4: Button {Radio 1}
68 4: Button {Radio 2}
69 4: Button {Radio 3}
70 3: Link {<a href="http://www.somecorp.com">This is a link!</a>}
71 3: Composite {}
72 4: Button {File}
73 4: Button {Directory}
74 4: Button {Color}
75 4: Button {Font}
76
ToolBar 包含 ToolItem, ToolItem 可以有文本或图片作为按钮。一般来说,要么使用图片(AKA 图标)、要么使用文本,不能同时使用。如果仅使用图片,那么 ToolItem 需要有一个 ToolTip (帮助提供信息的短语或句子),这样当鼠标停留在 ToolItem 上时,会显示 ToolTip,解释图片的功能。
ToolBar 必须定义成以下两种完全互异的样式之一:
HORIZONTAL —— 水平方向的
VERTICAL —— 垂直方向的
ToolBar 支持以下样式:
FLAT —— 以平面样式显示项目
WRAP —— 项目换行
RIGHT —— 项目右对齐(及左对齐)
SHADOW_OUT —— 显示阴影
ToolItem 必须定义成以下 5 种完全互异的样式之一:
CHECK —— 可连续选择项目(复选)。
DROP_DOWN —— 项目(通常)显示下拉菜单。
PUSH —— 项目作为按钮,可直接引发动作(最常见的形式)。
RADIO —— 此类项目只能选择一个。
SEPARATOR —— 在项目组之间充当分隔符(通常是一个条),这个项目没有功能。
以下两个清单分别显示了创建 ToolBar 和 ToolItem 的代码。
清单 2. 创建 ToolBar 的方法
2 return new ToolBar(parent, style | SWT.VERTICAL);
3 }
4
5 protected ToolBar createHToolBar(Composite parent, int style) {
6 return new ToolBar(parent, style | SWT.HORIZONTAL);
7 }
8
清单 3. 创建 ToolItem 的方法
2 Image image, String tooltip,
3 SelectionListener listener) {
4 if (image != null && (text == null && tooltip == null)) {
5 throw new IllegalArgumentException("image only items require a tool tip");
6 }
7 ToolItem ti = new ToolItem(bar, style);
8 if (image != null) {
9 ti.setImage(image);
10 }
11 else {
12 if (text != null) {
13 ti.setText(text);
14 }
15 }
16 if (tooltip != null) {
17 ti.setToolTipText(tooltip);
18 }
19 if (listener != null) {
20 ti.addSelectionListener(listener);
21 }
22 return ti;
23 }
24
多数操作系统都提供了与系统状态关联的特殊形式的工具栏,称为 托盘 (Tray)。不能构造 Tray;必须使用 Display.getSystemTray() 访问 Tray。与 ToolBar 相似,托盘中包含 TrayItem。TrayItem 没有样式选项,通常以 PUSH ToolItem 的形式工作。
CoolBar 类似 ToolBar,区别在于用户可以重新安排栏中的 CoolItem,可以在 CoolItem 之间拖曳分隔条。对于栏中的 CoolItem 如何换行以及栏中项目显示的顺序,CoolBar 还允许更多控制。CoolBar 只支持 FLAT (或 NONE)样式。CoolItem 只支持 DROP_DOWN 样式。与 ToolItem 不同,CoolItem 有相关的控件负责实际实现项目的 GUI。如果没有这个控件,CoolItem 就没有功能,通常也没有可视的实现。这个控件应当有一个 ToolTip。
下面两个清单分别显示了创建 CoolBar 和 CoolItem 的代码。请注意只能创建水平 CoolBar。
清单 4. 创建 CoolBar 的方法
2 return new CoolBar(parent, style);
3 }
4
清单 5. 创建 CoolItem 的方法
2 Image image, SelectionListener listener) {
3 CoolItem ci = new CoolItem(bar, style);
4 if (text != null) {
5 ci.setText(text);
6 }
7 if (image != null) {
8 ci.setImage(image);
9 }
10 return ci;
11 }
12
下面这个清单显示了如何用这个代码创建 CoolItem 和相关控件。在这个示例中,当选中 CoolItem 的控件时,会弹出一个菜单,如图 2 所示。请注意 CoolItem、按钮和菜单都用 CoolBar 作为双亲。还请注意 CoolItem 的文本没有显示,只显示了关联的控件。
清单 6. CoolItem 的创建示例
2 : // other CoolItems
3 CoolItem ci = createCoolItem(cb, SWT.FLAT, "Drop", null, null);
4 Button b = createButton(cb, SWT.PUSH, "Press Me 1", null, new SelectionAdapter() {
5 public void widgetSelected(SelectionEvent se) {
6 menu.setVisible(true);
7 }
8 });
9 ci.setControl(b); // associate Button with CoolItem
10 Menu m = new Menu(cb);
11 createMenuItem(m, SWT.PUSH, "Item 1", null, '1', true, null);
12 createMenuItem(m, SWT.PUSH, "Item 2", null, '2', true, null);
13 createMenuItem(m, SWT.PUSH, "Item 2", null, '3', true, null);
14 : // other CoolItems
15
图 2. CoolItem 示例
通常需要给应用程序 GUI 的某些部分分配可变的屏幕空间。第 3 部分 介绍了如何用 TabFolder 实现此目标。而本文将介绍使用 SashForm 的替代方法。
SashForm 显示多个(通常是两个)控件时,在控件间可以有分隔 Sash(框格)。可移动此框格,在控件间分隔屏幕空间。请注意在多数情况下,SashFrom 中的控件是 Composite。要获得非常好的使用性,Composite 应当有边框,以便让 Sash 看起来更清楚。SashForm 可以嵌套在其他 SashForm 中(看起来工作得很好),从而形成相当复杂的分隔空间的方法。SashForm 在 custom 包中。
SashForm 必须定义成以下两种互斥的样式之一:
HORIZONTAL —— 水平方向排列元素
VERTICAL —— 垂直方向排列元素
它们还支持 SMOOTH 样式,在使用此样式时,框格的移动更流畅。
以下清单显示了创建 SashForm 的方法。
清单 7. 创建 SashForm 的方法
2 SashForm sf = new SashForm(parent, style);
3 return sf;
4 }
5 protected SashForm createVSashForm(Composite parent) {
6 return createSashForm(parent, SWT.VERTICAL);
7 }
8 protected SashForm createHSashForm(Composite parent) {
9 return createSashForm(parent, SWT.HORIZONTAL);
10 }
11
图 3 和图 4 显示了 SashForm 的实际效果。图 3 展示的是外部的 SashForm 移动到右侧。图 4 则展示调整内部 SashForm 以使中央 Composite 变得更大。把这两个图与 图 1 对比,可以看出 Sash 预先配置的位置是,外部 Sash 20%,内部 Sash 33%。
图 3. SashForm 示例 1
图 4. SashForm 示例 2
CBanner 是带有定制、预定义布局的特殊 Composite。它支持三个控件:Left、Right 和 Bottom,这三个控件都是可选的;通常使用的是 Left 和 Right。一般来说这些控件是 ToolBar。CBanner 在 Eclipse 中被用来使主工具区恰好位于主菜单下。CBanner 在 custom 包中。
像 SashForm 一样,CBanner 提供了分隔器,可以容易地移动,从而分隔 Left 和 Right 控件之间分隔空间。CBanner 有一个 setSimple(boolean) 方法,控制分隔器的形式。如果为 false,分隔器就采用粗曲线形式。
以下清单显示了创建 CBanner 的代码。
2 return new CBanner(parent, SWT.NONE);
3 }
4
图 5 显示了一个简单的 CBanner 和一个复杂的 CBanner。
图 5. CBanner 示例
Link
Link 与 PUSH 按钮类似,但是看起来更像 Web 浏览器中的文本链接。Link 只支持文本内容。Link 可以使用普通文本或 HTML A 标记作为内容(通常采用 某些文本消息 的形式)。如果使用 A 标记的语法,那么 Link 看起来就像 Web 链接;否则,看起来就像 Label。请注意在 Eclipse V3.1 中才可以使用 Link。
以下清单显示了创建 Link 的代码。
清单 8. 创建 Link 的方法
2 SelectionListener listener) {
3 Link l = new Link(parent, SWT.NONE);
4 if (text != null) {
5 l.setText(text);
6 }
7 if (listener != null) {
8 l.addSelectionListener(listener);
9 }
10 return l;
11 }
12
图 6 显示了一个用红色强调的 Link。
图 6. Link 示例
有些时候,您可能希望在修改控件大小或移动控件的同时给用户提供反馈。Tracker 可实现此目的。它创建一个临时的轮廓(实际是 GUI 上的透明窗口的边框),可以通过键盘或鼠标移动它或修改大小。在关闭 Tracker 时,应用程序通常就把相关控件移动或修改尺寸到与 Tracker 匹配的位置和尺寸。应用程序也可以跟着 Tracker 持续地移动控件或修改控件大小。
以下清单显示了创建 Tracker 的代码。
清单 9. 创建 Tracker 的方法
2 return createTracker(parent, style, null, null);
3 }
4 protected Tracker createTracker(Composite parent, int style,
5 ControlListener cl, KeyListener kl) {
6 Tracker t = new Tracker(parent, style);
7 if (cl != null) {
8 t.addControlListener(cl);
9 }
10 if (kl != null) {
11 t.addKeyListener(kl);
12 }
13 return t;
14 }
15
图 7 显示了 Check 按钮的 Tracker,扩展到了 GUI 的右侧。
图 7. Tracker 示例
Dialog
BasicApplication 类显示了确定退出的 MessageBox。这个 MessageBox 就是 SWT 提供的一组标准对话框的一个示例。其他一些有用的对话框是:
FileDialog —— 允许用户选择文件
DirectoryDialog —— 允许用户选择目录
FontDialog —— 允许用户选择字体
ColorDialog —— 允许用户选择选择颜色值
请注意 Dialog 可能不允许您对其标题文本进行设置。
下面的清单显示了创建全部 4 种 Dialog 的代码。
清单 10. 创建多种 Dialog 的方法
2 FileDialog fd = new FileDialog(getShell(), SWT.OPEN);
3 fd.setText("Sample File Dialog");
4 String path = fd.open();
5
6 DirectoryDialog dd = new DirectoryDialog(getShell(), SWT.NONE);
7 dd.setText("Sample Directory Dialog");
8 String path = dd.open();
9
10 ColorDialog cd = new ColorDialog(getShell(), SWT.NONE);
11 cd.setText("Sample Color Dialog");
12 RGB rgb = cd.open();
13
14 FontDialog fd = new FontDialog(getShell(), SWT.NONE);
15 fd.setText("Sample Font Dialog");
16 FontData d = fd.open();
17
图 8 至图 11 显示了不同 Dialog 的实际效果。
图 8. 文件对话框示例
图 9. 目录对话框示例
图 10. 颜色选择示例
图 11. 字体选择示例
结束语
本系列的第 4 部分介绍了 SWT 的控件 ToolBar、CoolBar、Tray、Link、SashForm、CBanner、Tracker 和不同的 Dialog。我们现在完成了对 SWT GUI 控件的游历。本系列的下一篇文章将进入 JFace 的领域,介绍如何使用 JFace ContentProvider 和 LabelProvider 构建表格和树的模型。
代码下载:os-jface4.zip