首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 开源 FAQ 第二书店 博文视点 程序员
频道: 研发 数据库 中间件 信息化 视频 .NET Java 游戏 移动 服务: 人才 外包 培训
    图书品种:235680
       
热门搜索: ASP.NET Ajax Spring Hibernate Java

3.2  SWT基本窗口组件

上一节介绍了SWT程序开发中的一些基础知识,本节将通过实例介绍SWT的基本窗口组件,它们简单易用,并且在实际开发中,会被经常用到。本节先介绍最简单的控制组件,包括Label、Text、Button等,这些组件通常使用在对话框中,当然也会直接布置在Shell中;在熟悉了这些组件后,再介绍一些相对复杂的组件,包括Combo、Menu等。

3.2.1  Label

Label是使用最广泛的窗口组件,打开任何一个对话框都能够看到它的存在。它用于在窗口中显示文本数据、图像以及作为分隔符使用。这里分隔符是指在图形界面中的一条横线或竖线,用于分隔不同的组件元素,如表3-5所示。

表3‑5                                                       Label类的构造函数

构 造 函 数

描    述

Label(Composite parent, int style)

Label组件的父亲组件必须是Composite类型

Composite也是Widget的一个子类,该类的设计遵从设计模式中的Composite模式。它能够存放其他的组件,后文中介绍到的Table以及Tree等组件,分别用来存放表格数据和继承结构的数据,它们都是Composite的子类。Shell类也是它的子类,因此Shell组件可以作为父亲放置Label组件,如表3-6所示。

表3‑6                                                           类Label的样式

样    式

描    述

SEPERATOR

该Label作为一个分隔符,此时不能向该Label对象设定文本或图片

HORIZONTAL

当作为分隔符时,该分隔符为水平

VERTICAL

当作为分隔符时,该分隔符为垂直

SHADOW_IN

当作为分隔符时,该分隔符凹陷

SHADOW_OUT

当作为分隔符时,该分隔符凸出

SHADOW_NONE

当作为分隔符时,该分隔符无阴影

CENTER

文本/图片在Label组件中居中

LEFT

文本/图片在Label组件中居左

RIGHT

文本/图片在Label组件中居右

WRAP

该Label组件支持“包装”功能

表中前6个样式用于Label组件作为分隔符的情形,接下来的3个组件则是当该组件作为文本或图片的载体时,用来控制这些内容的位置。当Label中文本内容长度过长,其父亲组件内无法在一行内完全显示该内容时,Label组件会对该内容进行“包装”,比如换行显示等。

实例3-1  Label的使用

实例3-1显示如何在程序中使用Label组件,如代码3-5所示。读者目前可以忽略Layout对象,在3.4节中会详细介绍Layout的含义和功能。

代码  3-5

public class LabelEg {

     public static void main(String[] args) {

          Display display = new Display();

          Shell shell = new Shell();

          shell.setLayout(new GridLayout(1, false));

           

// 创建包含边界的Label对象

          Label label1 = new Label(shell, SWT.BORDER);

             // 该Label为文本Label

          label1.setText("This is a text Label with border.");

             // 创建作为水平分隔符的Label对象

          Label label2 = new Label(shell, SWT.HORIZONTAL | SWT.SEPARATOR);

          label2.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

          Image image = new Image(display, "label.jpg");

         

             // 创建作为图片容器的Label对象,该图片在Label中居中

Label imageLabel = new Label(shell, SWT.CENTER);

          imageLabel.setImage(image);

          imageLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));

          shell.pack();

          shell.open();

          while (!shell.isDisposed()) {

               if (!display.readAndDispatch()) {

                    display.sleep();

               }

          }

          display.dispose();

     }

}

运行代码3-5,结果如图3-11所示。根据组件关联的Layout不同,其占用的空间也不相同。通过改变程序主窗口的大小,可以看出图片始终居于imageLabel组件的中部。Label属于静态控制组件,也就是说,用户无法通过鼠标单击或者选择Label中的内容,更无法使用键盘修改其中的内容。

图3-11  代码3-5的运行结果

3.2.2  Button

Button是非常常见的一个控制组件,比如消息对话框中的“Yes”、“No”按钮就是Button组件,用户通过Button按钮来触发一些事件。在SWT中,这种功能的Button称作Push Button。除了作为Push Button外,SWT的Button组件还有其他丰富的功能,比如图形用户界面中常见的Checkbox,Radio Button等功能,都能够用SWT的Button类来实现。与Label类相同,Button类的构造函数也需要两个参数,其中一个作为其父亲组件,该组件必须是Composite类型;另一个参数则是该Button的样式,通过这些不同的参数,Button类从功能上能够充当Push Button,Radio Button等,表3-7列出了Button类的样式类型,与其他样式相同,这些样式也都定义在org.eclipse.swt.SWT中。

1.样式

表3‑7                                                    窗口组件Button的样式

样    式

描    述

ARROW

该Button为箭头样式

CHECK

创建一个Checkbox勾选框

PUSH

创建一个Push Button

RADIO

创建一个Radio Button,一组Radio Button中只能有一个被选中

TOGGLE

创建一个Toggle Button,它能够保存当前该Button是否是按下的状态

FLAT

该Push Button的样式为扁平状

UP

向上的箭头

DOWN

向下的箭头

CENTER

该Button上显示的文字居中

LEFT

该Button上显示的文字居左,如果与ARROW样式同时使用,则表示向左指的箭头

RIGHT

该Button上显示的文字居右,如果与ARROW样式同时使用,则表示向右指的箭头

SWT在设计过程中,将功能相似的控制组件设计为一个类,通过向这个类的构造函数传递不同的样式来改变组件的外观与状态,而不是通过继承的方式实现这些外观及功能上的细微差别。这种设计有效控制了组件的类型,避免了类继承层次过分深入。

实例3-2  不同样式的Button

实例3-2是使用Button类的一个例子,如代码3-6所示,shell对象的setLayout()方法用于设定shell窗口的布局。可以看出,创建不同的Button只要根据改变样式参数即可,因为PUSH、CHECK、RADIO等样式分别代表了不同的Button类型,因此这几个样式不能相互组合。必须注意,样式在创建Button时传递,此后就不能够再修改它的值了。

代码  3-6

public class ButtonEg {

     public static void main(String[] args) {

          Display display = new Display();

          Shell shell = new Shell(display);

          shell.setLayout(new GridLayout(2, true));

          // 创建两个Push Button

          new Button(shell, SWT.PUSH).setText("Push 1");

          new Button(shell, SWT.PUSH).setText("Push 2");

          // 创建两个勾选框

          new Button(shell, SWT.CHECK).setText("Checkbox 1");

          new Button(shell, SWT.CHECK).setText("Checkbox 2");

          // 创建两个Radio Button

          new Button(shell, SWT.RADIO).setText("Radio 1");

          new Button(shell, SWT.RADIO).setText("Radio 2");

          // 创建两个Toggle Button

          new Button(shell, SWT.TOGGLE).setText("Toggle 1");

          new Button(shell, SWT.TOGGLE).setText("Toggle 2");

          // 创建两个Flat Button

          new Button(shell, SWT.FLAT).setText("Flat 1");

          new Button(shell, SWT.FLAT).setText("Flat 2");

          shell.pack();

          shell.open();

          while (!shell.isDisposed()) {

               if (!display.readAndDispatch()) {

                    display.sleep();

               }

          }

          display.dispose();

     }

}

运行代码3-6,结果如图3-12所示,该程序显示了各个不同样式的Button组件在外观和工作方式上的不同。Push Button非常简单,它的目的就是触发选择事件;Checkbox和Radio Button常用于“属性”对话框中,用于显示用户对属性的配置。该程序具有两个Radio Button,这种情况在实际开发中不应该出现,因为总是可以使用一个Checkbox来替换两个Radio Button,这样做更节省屏幕空间。

当在Push Button上按下鼠标时,该按钮被重新绘制,它的状态看上去凹陷下去,此时释放鼠标按钮,则会触发一个选择事件。但是如果释放鼠标按钮是在按钮图形之外,则没有任何事件被触发,Push Button是无状态的。与Push Button不同,Checkbox、Radio Button和Toggle Button都具有选择状态,这些状态能够通过getSelection()方法获得,同时也能够通过setSelection(boolean) 方法进行设定,但是调用这个set方法不会触发选择事件,只有用户通过鼠标或键盘进行选择时,选择事件才会被触发。通常使用这个set方法对这些Button设定初始值。

图3-12  代码3-6的运行结果

2.事件

目前本书还没有对SWT的事件进行详细的介绍,这里给出选择事件的一个例子,说明事件的使用方法。在实际程序中,用户单击Push Button后,程序总是应该有所动作,也就是说,应该对Push Button的选择事件做出响应;而对于Checkbox和Radio Button则视情况而定。

实例3-3  监听Button的选择事件

代码3-7给出监听事件的实例,该实例中创建了两个选择事件监听器对象(SelectionListener),分别监听Push Button和Radio Button。程序通过setSelection(boolean)方法设定了Radio Button的初始值。

代码  3-7

public class ButtonEg2 {

     public static void main(String[] args) {

          Display display = new Display();

          Shell shell = new Shell(display);

          shell.setLayout(new GridLayout(1, true));

           

// 创建Push Button,用于显示两个Checkbox的状态

          final Button pb = new Button(shell, SWT.PUSH);

          pb.setText("Display Checkbox Status");

           

// 创建两个Checkbox勾选框

          final Button cb1 = new Button(shell, SWT.CHECK);

          cb1.setText("Checkbox 1");

             // 初始化该Checkbox为勾选状态

             cb1.setSelection(true);

          final Button cb2 = new Button(shell, SWT.CHECK);

          cb2.setText("Checkbox 2");

           

             // 创建两个Radio Button,第一个选中时,Push Button可点,

             // 第二个选中时,Push Button被禁止

          final Button rb1 = new Button(shell, SWT.RADIO);

          rb1.setText("Enable Push");

          rb1.setSelection(true);

          final Button rb2 = new Button(shell, SWT.RADIO);

          rb2.setText("Disable Push");

             // Push Button必须有监听事件,该监听器获得Checkbox的当前状态,

             // 并打印在控制台

          pb.addSelectionListener(new SelectionAdapter() {

              public void widgetSelected(SelectionEvent e) {

                   // getSelection()方法用于获得checkbox的选择状态

String status1 = cb1.getSelection() ? "selected"

                            : "not selected";

                   String status2 = cb2.getSelection() ? "selected"

                            : "not selected";

                   System.out.println("checkbox1: " + status1);

                   System.out.println("checkbox2: " + status2);

               }

          });

          // 为rb1添加选择事件监听器,当其被选中时设定Push Button不可点

          rb1.addSelectionListener(new SelectionAdapter() {

               public void widgetSelected(SelectionEvent e) {

                   pb.setEnabled(rb1.getSelection());

               }

          });

          shell.pack();

          shell.open();

          while (!shell.isDisposed()) {

               if (!display.readAndDispatch()) {

                    display.sleep();

               }

          }

          display.dispose();

     }

}

运行代码3-7,结果如图3-13所示,该图显示了程序的初始状态。此时Push Button可以单击,Checkbox和Radio Button也都根据初始值选定。此时单击Push Button,会触发该按钮的选择事件,Display对象从操作系统获取该事件,并最终调用该事件的监听器对象的widgetSelected()方法。如果在该按钮上按下鼠标,并将鼠标移至按钮之外并释放按钮,不会有任何事件触发。以这两种方式单击“Display Checkbox Status”按钮,查看控制台的打印信息。

图3-13  代码3-7的运行结果

单击“Disable Push”Radio Button,此时Push Button呈灰色,如图3-14所示,这时无法单击“Display Checkbox Status”按钮。

图3-14 “Display…”按钮被屏蔽

另外注意,在代码3-7中,可以将“Enable Push”Radio Button的初始值设定为false,这样程序在运行时,Radio Button中被选择的是“Disable Push”按钮,但是Push Button仍然可单击,因为前文解释过,直接调用setSelection(boolean)方法不会触发选择事件。

SWT的窗口组件中,一些方法在含义上与窗口事件关联,比如这里的setSelection(boolean)方法与Button的选择事件关联,但是调用这些方法不会触发事件;而另一些方法,比如下文中的Combo组件,其setSelection(int index)方法则会触发选择事件,这一点,读者应注意。