几种特殊的部件
好像因为大家的抱怨比较多,感觉这一段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文档的翻译了。当然如果以后有充足的时间的话,我也希望能够向大家多介绍一些相关的内容。