SWT (标准窗口小部件工具箱,Standard Widget Toolkit)是在 Eclipse 平台上使用的窗口小部件工具箱。它也可以作为 Swing/AWT 的一个重要替代产品,用于构建任何类型的 Java GUI 应用程序。随着 Eclipse 平台在过去两年里的日趋流行,SWT 已经进入大家的视线,并且最近它已经开始在一些应用程序中取代 Swing/AWT。SWT 的流行源自这样一个事实:它是跨平台的工具箱,利用了窗口小部件的本性,并有一个与 Swing 及其他现代工具箱同样强大的功能。使用 SWT,就不用在可移植性、功能和性能之间做取舍了。
事实上,Swing/AWT 只在一个方面明显强于 SWT,这就是 Java 2D。Java 2D 是一个强大的 API,是在 JDK 1.2 中引入的。它使 Java 开发人员在 AWT 组件上绘制时可以使用复杂的二维变换(平移、旋转、缩放、错切等)。不幸的是,Java 2D 设计为只在 AWT 或者 Swing 工具箱上使用,而 SWT 还没有提供这种扩展的二维能力。因此,许多开发人员发现他们必须选择是在 Java 平台上使用 Java 2D 还是放弃它令人兴奋的功能而使用 SWT。
不过,在本文中您将了解到如何同时拥有这两方面的好处。我将展示一个简单的技术,利用该技术可以在 SWT 组件和 Draw2D 图像上绘制 Java 2D 图像。为了理解这个例子,读者应当熟悉 Java 2D、AWT 和 SWT。具有一些 Eclipse 平台的 GEF(图形编辑框架,Graphical Editing Framework)的经验也是有帮助的。
屏外图像技术
本文展示一种简单的技术,利用该技术,您可以用 Java 2D 功能在任何 SWT 窗口小部件或者 Draw2D 图像上绘制。为了弥补 SWT 上缺少 Java 2D 的不足,用一个屏外(offscreen)AWT 图像接收 Java 2D 绘制操作,并将它们转换为独立于工具箱的像素值。再用另一个由 SWT 工具箱创建的 屏外图像将这些像素信息绘制在任何 SWT 组件上。图 1 显示了 AWT 屏外图像转换为 SWT 图像再绘制在 SWT 窗口小部件上的过程。
图 1. 屏外图像技术允许在 SWT 上使用 Java 2D
图 1 中显示的屏外 AWT 图像被初始化为透明背景。然后对屏外图像的图形上下文调用 Java 2D 方法。像所有 AWT 图像一样,屏外图像的图形上下文自动支持 Java 2D。完成了所有特定于 Java 2D 的绘制后,提取 AWT 图像的像素值并传送到一个屏外 SWT 图像中。然后用工具箱的 GC.drawImage(...) 方法在 SWT 组件上绘制这个 SWT 图像,就像所有正常图像一样。
我将在下面几节中完成这个过程中的每一步。
创建 AWT 屏外图像
对于 AWT 屏外图像,要使用 java.awt.image.BufferedImage 实例。BufferedImage 是一个可以通过它的 API 访问其像素数据的图像。访问到了图像的像素值就可以在以后将它转换为 SWT 图像。
构建一个 AWT 缓冲图像的最简单方法是使用构造函数 public BufferedImage(int width, int height, int imageType)。前两个参数表明图像具有的大小。第三个参数是指定要创建的图像 类型 的常量。图像类型 —— 可能的值是在类 BufferedImage 中声明的常量 TYPE_XXX 之一 —— 表明像素值是如何存储在图像中的。在彩色图像中一般使用以下几种最重要的图像类型:
TYPE_BYTE_INDEXED:这种图像类型的图像将使用一个索引颜色模型。索引颜色模型的意思是图像中使用的每一种颜色都是在一组颜色中索引的。像素值只包含这个像素的颜色在颜色模型中的索引。这种类型的图像局限于 256 种颜色 —— 也就是颜色模型的大小。以这种方式存储像素信息可以很紧凑地表示图像,因为每一个像素都只用一个字节编码。
TYPE_INT_RGB:
这种类型常量表明图像使用直接颜色模型。直接颜色模型 的意思是每一个像素的值包含关于其颜色的完整信息。TYPE_INT_RGB 表明每一个像素都是用一个整数(四字节)编码的。每一个像素中编码的信息是这个像素所使用的颜色的红、绿和蓝(RGB)成分。每一种颜色成分都用一个字节编码。因为整个像素值是用四个字节编码的,所以有一个字节是未使用的。这种图像的内部表示占用的内存是使用索引颜色模型的图像的四倍,但是这种图像可以使用的颜色数增加到了 1 百 60 万(256 x 256 x 256)。
TYPE_INT_ARGB:
与 TYPE_INT_RGB 一样,这种类型的图像使用直接颜色模型并用四个字节编码每一个像素。不同之处在于,这里用 TYPE_INT_RGB 没有使用的第四个字节表示像素的透明度,有时也称为颜色的 alpha 成分。这种类型的图像可以有透明的背景,也可以是半透明的。 为了让屏外图像技术可以工作,需要只将受到 Java 2D 绘制影响的像素传送到 SWT 组件的表面。为了保证这一点,初始图像必须有透明背景。因此,对于 AWT 屏外图像,使用的缓冲图像类型为 TYPE_INT_ARGB。
绘制和提取图像
这个过程的下一步是用 Java 2D 绘制图像。首先取得它的 Graphics2D 上下文。可以用方法 createGraphics2D() 或者调用 getGraphics() 做到这一点。在这个上下文上绘制将会自动修改图像的像素数据。在绘制完成后,可以用方法 getRGB(int startX, int startY, int w, int h, int rgbArray, int offset, int scansize) 容易且高效地提取图像的像素值。这个方法可以将图像中矩形区域的像素数据传输到一个整数数组中。getRGB() 方法的参数如下:
startX, startY 是要提取的区域左上角图像的坐标
w, h 是要提取的区域的宽度和高度
rgbArray 是接收像素值的整数数组
offset 是数组中接收第一个像素值的位置的索引。
scansize 是图像中相邻两行中具有相同行索引的像素的索引偏移值。如果这个值与要提取的区域的宽度相同,那么一行的第一个像素就会存储在数组中前一行最后一个像素后面的索引位置。如果这个值大于提取区域的宽度,那么数组中,在一行最后和下一行开始之间就会有一些未使用的索引。
存储像素数据
图 2 显示 BufferedImage.getRGB(...) 如何在提取了 AWT 图像的矩形区域后填充整数缓冲区。图中下面的部分表示整数缓冲区。每一个框表示缓冲区中包含一个像素 4 字节 ARBG 值的一个值。括号中的数字表示像素在图像中的坐标。
图 2. 从 AWT 图像中提取像素值
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/