SWT/JFace开发入门指南(七)〈转帖〉
几种特殊的部件
好像因为大家的抱怨比较多,感觉这一段 csdn 的 blog 似乎又有恢复稳定的迹象了, ^_^ 。
前面的两节中,我都没有作一些详细的介绍,而是推荐了两篇文章给大家,可能你会觉得有点不习惯,不过我觉得作为一个软件开发者来说,最重要的一个技能就是你要能够找到自己所需要的资源。而在 swt ( JFace )开发方面呢,其实如果你能多看一看 eclipse 的联机帮助和官方网站上的各种文档的话,对你的开发一定会大有帮助。其实我也都是这样一步一步慢慢熟悉了的。
在这一节中,我要向大家介绍几种比较特殊的 widget ,包括 Composite , Menu 等。
Composite
其实我们已经接触过 Composite 了,我们前面介绍过 Shell , Shell 就是一种特殊的 Composite 。就如它的名字一样, Composite 指的是可以嵌套其他部件的一种部件。
我们先来看一段代码,为了看起来更简明,我把 shell 创建之类的代码都去掉了。
composite.setLayout( new RowLayout(SWT.VERTICAL));
Text text = new Text(composite,SWT.NONE);
text.setSize( 100 , 30 );
代码段 9
这段程序意义不大,不过我们可以看出, Composite 可以作为其他部件的 parent ,可以有自己的 Layout 。
我们在其中定义 composite 的风格时候用到了 SWT.V_SCROLL ,这是用来做什么的呢?它是用来定义这个部件有纵向滚动条的。当然相应当 SWT.H_SCROLL 就定义了部件有横向滚动条。
那么什么样的部件可以有滚动条呢?只要是 org.eclipse.swt.widgets.Scrollable 的子类就可以使用这两个风格定义自己的滚动条。这是我们顺便提到的一点题外话。
如果你把上面的程序填充完整运行一下的话会发现出来的样子很难看。因为 Composite 本身是看不到的。而可以孤零零地看到一个突出的滚动条在那里。所以实际上单独使用 Composite 意义不是很大,我们可以使用它的一些子类。
打开 Composite 的 javadoc ,你会发现它的子类实在是太多了。我们只拣两个介绍一下, Group 和 TabFolder 。
比起 Composite 来, Group 有一个边框,你可以用 setText 方法设定它的标题。所以这样在视觉上会更好看一些。下面是一个 Group 的图示:
图 11
另外一种特殊 Composite 就是 TabFolder , TabFolder 允许我们定义标签页式的窗体。就像下面图示的那样:
图 12
我们怎么设定各个标签呢?答案是使用 TabItem 。可以使用 TabItem 的 setControl 方法设定标签页上的控件。但是这样又出现了一个疑问, setControl 中的参数不是数组,如果我们想设定好几个控件应该怎么办呢?这个时候就用得上 Composite 了。我们可以首先建一个 Composite 实例,然后在里面添加控件,再把这个 Composite 实例本身作为参数传递给 TabItem 的 setControl 方法。
为了更清楚地说明,我们可以看一下下面这段代码:
2
3 /* *
4 * @param args
5 */
6 public static void main(String[] args) {
7 Display display = new Display();
8
9 Shell shell = new Shell(display, SWT.DIALOG_TRIM);
10 shell.setLayout( new RowLayout(SWT.HORIZONTAL));
11 shell.setText( " TabFolder Demo " );
12
13 TabFolder tf = new TabFolder(shell, SWT.NONE);
14 tf.setLayout( new FillLayout());
15 TabItem ti = new TabItem(tf, SWT.NONE);
16 ti.setText( " A Simple TalItem " );
17 Composite composite = new Composite(tf, SWT.NONE);
18 composite.setLayout( new GridLayout( 2 , true ));
19
20 for ( int i = 0 ; i < 3 ; i ++ ) {
21 Label label = new Label(composite, SWT.RIGHT);
22 Text text = new Text(composite, SWT.NONE);
23 label.setText( " Text " + i + " : " );
24
25 }
26
27 ti.setControl(composite);
28
29 shell.pack();
30 shell.open();
31
32 while ( ! shell.isDisposed()) {
33 if ( ! display.readAndDispatch()) {
34 display.sleep();
35 }
36 }
37 display.dispose();
38 }
39 }
40
代码段 10
菜单( Menu )
swt 中和菜单相关的两个类是 Menu 和 MenuItem 。顾名思义, Menu 代表的就是整个菜单,而 MenuItem 是菜单中一项一项的实体。打个不恰当的比方来说, Menu 就好比一个书架,而 MenuItem 就是书架上一个一个的格子。
创建菜单
如果我们要创建一个菜单,可以根据下面步骤来进行:
1. 实例化一个 Menu 对象, Menu 有好几种格式的构造函数,你可以选择一个,比如像这样:
与其他部件不同的是, Menu 的父控件并不一定需要是 Composite ,而是任何一个 Control 都可以。而 Menu 的风格有几种:
l SWT.POP_UP :弹出式菜单
l SWT.BAR :程序中的顶级菜单,比如我们通常看到的包含了 “ 文件,编辑 ” 之类的那个横列的菜单栏
l SWT.DROP_DOWN :下拉式菜单,比如我们在 Word 点击 “ 文件 ” 之后出现的子菜单就是一个典型的下拉式菜单。
注意 Menu 本身是没有 setText 方法的,因为这些具体的显示属性你必须在相应当 MenuItem 中设定。
2. 为 Menu 添加 MenuItem 对象,一个 MenuItem 的构造函数如下所示:
或者是:
其中 parent 就是所属的 Menu ,而 index 可以看成是排列顺序。而 style 可以有以下几种:
l SWT.PUSH :就是一个普通道菜单项,但是这样的 MenuItem 不能有层叠的下一级菜单
l SWT.CASCADE: 这样的 MenuItem 可以有层叠的下一级菜单。可以使用 MenuItem 的 setMenu 方法设定它的下一级菜单,作为参数的 Menu 风格必须是 SWT.DROP_DOWN
l SWT. SEPARATOR: 分隔符,也就是一道横线,这样的 MenuItem 是没有文字的,所以 setText 不起作用。
l SWT.CHECK: 菜单项前面有一个复选标志。
l SWT.RADIO: 菜单项前面有单选标志。
下面的图示说明了各种风格不同的 Menu 和 MenuItem
图 13
3. 为有下级菜单的 MenuItem (风格必须为 SWT.CASCADE )设定下级菜单的 Menu 对象(用 setMenu 方法),当然了,你仍然需要为这个下一级的 Menu 设定其中的 MenuItem
4. 如果你的菜单风格式 SWT.BAR ,你还需要调用 Shell 的 setMenuBar (参数就是顶级菜单)方法设定窗体菜单。如果是弹出式菜单也就是 SWT.POP_UP ,你需要调用所在控件的 setMenu 方法设定弹出菜单为该菜单。
处理菜单事件
菜单的事件处理最主要的还是选择菜单项时候要进行的一些动作,我们可以用 SelectionListener 进行处理。你也可以为菜单展开的事件添加 ArmListener 。
下面这段简单的代码展示了一个只有退出程序功能的文件菜单。
2
3 private Shell _shell;
4
5 /* *
6 * @return Returns the _shell.
7 */
8 public Shell getShell() {
9 return _shell;
10 }
11
12 /* *
13 * @param _shell
14 * The _shell to set.
15 */
16 public void setShell(Shell shell) {
17 this ._shell = shell;
18 }
19
20 public MenuDemo() {
21 Display display = new Display();
22 Shell shell = new Shell(display, SWT.SHELL_TRIM);
23 setShell(shell);
24 shell.setLayout( new RowLayout(SWT.HORIZONTAL));
25 shell.setText( " Menu Demo " );
26
27 Menu menubar = new Menu(shell, SWT.BAR);
28 MenuItem fileitem = new MenuItem(menubar, SWT.CASCADE);
29 fileitem.setText( " &File " );
30
31 Menu filemenu = new Menu(shell, SWT.DROP_DOWN);
32 fileitem.setMenu(filemenu);
33 MenuItem exititem = new MenuItem(filemenu, SWT.PUSH);
34 exititem.setText( " &Exit " );
35 exititem.addSelectionListener( new SelectionAdapter() {
36 @Override
37 public void widgetSelected(SelectionEvent arg0) {
38 MessageBox messagebox = new MessageBox(getShell(), SWT.YES | SWT.NO);
39 messagebox.setText( " Exit " );
40 messagebox.setMessage( " Exit the program? " );
41
42 int val = messagebox.open();
43 if (val == SWT.YES)
44 {
45 getShell().close();
46 }
47 }
48
49 });
50 shell.setMenuBar(menubar);
51 shell.setSize( 800 , 300 );
52 shell.open();
53
54 while ( ! shell.isDisposed()) {
55 if ( ! display.readAndDispatch()) {
56 display.sleep();
57 }
58 }
59 display.dispose();
60 }
61
62 public static void main(String[] args) {
63
64 MenuDemo demo = new MenuDemo();
65 }
66
67 }
68
代码段 11
加速键
在使用 MenuItem 的 setText 方法时,可以在希望设为加速键的字母前面标 & ,比如
就标明了这个退出菜单项的加速键为 E 。
另外也可以使用 setAccelerator 方法设定加速键。
ToolBar 和 CoolBar
在这里,我要向大家说一声 sorry 了,因为我并不打算在这里详细介绍 Toolbar 的各种用法,这主要有两个原因:
1. 工具栏的用法和菜单是类似的,菜单是在实例化一个 Menu 对象以后添加 MenuItem ,而工具栏则是在实例化 ToolBar 以后添加 ToolItem (或者实例化 CoolBar 以后添加 CoolItem )。甚至它们的一些风格,事件也很类似。如果你对照着 ToolBar 和 ToolItem ( CoolBar,CoolItem )的 API 文档以及前面我对菜单用法的介绍看到话,很快就能比较熟悉工具条的用法。
2. 我们在后面介绍 JFace 的时候,你会发现有更简单的办法创建菜单和工具条。
小结
这一节介绍了几种有限的部件,关于 swt 的介绍到这一节为止就暂时告一段落了。在以后的部分我会开始给大家介绍 JFace 。当然了,这并不意味着以后再也没有 swt 的内容介绍给大家了,只是我觉得到现在为止,大家应该已经可以写一些简单的 swt 程序了,我如果再多介绍,就类似于对 API 文档的翻译了。当然如果以后有充足的时间的话,我也希望能够向大家多介绍一些相关的内容。