SWT教程

一个完整的SWT程序

下面的代码是一个完整的SWT程序,该程序创建一个标准的Windows窗口应用程序。

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

public class HelloSWT {

      public static void main (String[] args) {

          Display display = new Display();

          Shell shell = new Shell(display);

          shell.open();

          while (!shell.isDisposed()) {

              if (!display.readAndDispatch()) {

display.sleep();

}

          }

          display.dispose();

}

}

SWT能够运行在多种不同的平台上,它使用平台上的窗口组件作为程序的工作及显示方式。因此在Windows平台上开发的SWT程序可以运行在Linux之上,并且在Linux上运行时其外观使用Linux的窗口主题。

Widget

Widget既是SWT中所有窗口组件的抽象基类,也是SWT中一个非常重要的概念。在SWT应用程序中,窗口组件是用户与程序交互的接口。它是信息的载体。它将程序的数据呈现在图形化的窗口中,同时它自身包含一定的状态。在不同的状态下,其自身的显示也会有所不同。窗口组件还用于监听用户事件,它会根据鼠标和键盘事件改变其状态。

SWT使用平台窗口组件,因此当创建一个SWT Widget的对象时,与操作系统相关的组件将会被创建。当这些SWT对象被销毁时,相应的平台组件也会被释放。

1创建Widget

1列出了Widget类的构造函数。

1                                                         Widget类的构造函数

    

Widget(Widget parent, int style)

创建窗口组件对象。该组件的父亲为parent,该组件的行为和外观由style决定。

Widget类是一个抽象类,它不能够被实例化。但是大部分SWT窗口组件类都继承自该类,因此这里所说的Widget类的创建时特性适用于它的子类。在大多数情况下,创建一个Widget对象需要传递一个父Widget对象。该父亲窗口组件对其孩子组件的生命周期具有一定的控制。当父亲组件消亡时,其孩子组件也消亡。不同的组件类其允许的父亲组件有所不同。比如TabItem的父亲必须是TabFolderTreeItem的父亲可以是Tree或者TreeItem

创建Widget实例对象时需要传递的另一个参数是style,该参数限定了组件的行为和外观。比如在创建Tree组件时,可以使用SWT.SINGLE参数,该参数说明创建的树组件中不能够同时选中多个元素;当然也可以使用SWT. MULTI参数。

在创建Widget对象时,样式参数可以是单个值, 也可以是多个样式的组合。比如在创建Tree组件时,可以使用SWT.SINGLESWT.CHECK的组合,后者表示树中的每一个元素都有一个勾选框。当然,在创建Tree组件时可以传入SWT.MULTI | SWT.SINGLE,虽然这在逻辑上不成立,但是不会有任何编译错误。在样式矛盾的情况下,树组件会使用SWT.SINGLE

所有的样式都以常量的形式定义在org.eclipse.swt.SWT类中。

不同的组件有不同的样式,在SWTJava Doc中列出了每个SWT 组件所允许的样式。在SWT中,每个组件都能够应用其父亲组件所对应的样式。

2释放Widget

为了高效管理系统资源,SWT的设计中要求SWT程序直接管理这些资源。Widget类中提供了一个名为dispose()的方法,在SWT的开发过程中,会常和该方法打交道。该方法用于释放与组件相关的资源。

关于窗口组件的释放,有以下两个准则。

准则1 主动创建它则主动释放它

这个准则的含义是,当在程序中使用new创建了一个 组件对象,就应该调用dispose()方法来释放它。比如在HelloSWT程序的最后,display被释放就是通过调用dispose方法实现的。需要指出的是,display并不继承自Widget类,但是在组件释放的概念上,它们是一致的。

准则2 释放组件时其孩子组件也会被释放

按照准则1的概念,那么在HelloSWT程序中, 也应该调用Shell对象的dispose()方法来释放其孩子组件。其实不然,当释放一个组件时,其孩子组件也会被释放,比如在释放一个Tree组件 时,其中的各个元素(TreeItem组件)也会被自动释放,因此不需要主动调用这些孩子组件的dispose()方法。

当调用组件的dispose()方法时,与其对应的平台组件将被释放,但是此时该组件对象仍然存在。此时调用该对象的方法会有什么结果呢,如代码2所示。

代码2

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;

public class HelloSWT {

      public static void main (String[] args) {

          Display display = new Display();

          Shell shell = new Shell(display);

          shell.setText("HelloSWT");

          shell.open();

          while (!shell.isDisposed()) {

            if (!display.readAndDispatch()) display.sleep();

          }

          display.dispose();

          shell.setText("it is wrong!");

}

}

运行代码2,该程序能够正常启动并显示,但是当关闭程序时,会抛出SWTException异常,如代码3所示。

代码3

Exception in thread "main" org.eclipse.swt.SWTException: Widget is disposed

       at org.eclipse.swt.SWT.error(SWT.java:2942)

       at org.eclipse.swt.SWT.error(SWT.java:2865)

       at org.eclipse.swt.SWT.error(SWT.java:2836)

       at org.eclipse.swt.widgets.Widget.error(Widget.java:395)

       at org.eclipse.swt.widgets.Widget.checkWidget(Widget.java:297)

       at org.eclipse.swt.widgets.Shell.open(Shell.java:815)

       at first.HelloSWT.main(HelloSWT.java:16)

因此当一个组件的dispose()方法被调用,该组件正常释放之后,就不能够再对该组件对象以及其孩子组件对象进行任何操作了。从理论上来说,SWT的设计所引发的该问题的确不怎么光彩,但是在实际开发中,这个问题非常容易避免。 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值