s
SWT 提供了功能强大的图形引擎以在小窗口中绘图和显示图像。即使以前没有为图形界面编程,您也可以做得相当好,原因是小窗口负责处理图标、文本和其它数据的绘制。但是,如果您的应用程序显示定制图形,或者如果您正在实现定制绘制的小窗口,则将需要了解 SWT 中的一些基本绘图对象。
图形上下文 GC 是 SWT 图形支持的焦点。它的 API 描述 SWT 中的所有绘图功能。
GC 可用于在控件(这是最常见的情况)、图像、屏幕或打印机上绘图。当在控件上绘图时,使用在控件的绘图事件中为您提供的 GC。当在图像、屏幕或打印机上绘图时,必须创建为它配置的 GC,并在使用完它时除去 GC。
一旦获得了 GC,您就可以设置它的属性,例如,颜色、行宽和字体,它们控制在 GC 中绘制的图形的外观。
GC 的“API 参考”描述一组完整的图形功能。
当处理 SWT 中的字体时,使用字体和 FontData 类。
FontData 描述字体的特征。可以通过指定字体名、样式和大小来创建 FontData。FontData 包含用于查询这些属性的 API。由于 FontData 不分配任何 OS 资源,因此不需要除去它。
字体是表示在绘图 API 中使用的字体的实际图形对象。通过指定想要的字体的显示和 FontData 来为显示创建字体。也可以通过查询字体来获取它的 FontData。
当使用完已分配的字体时,必须除去它。
颜色的处理与字体是相似的。通过为期望的颜色指定 RGB 值来为显示创建颜色。当使用完已分配的颜色时,必须除去它。
显示方法 getSystemColor(int) 允许您查询 OS 平台预定义的系统颜色。不应该释放使用此技术所获得的颜色。
在 SWT 颜色模型这篇文章中详细讨论了颜色模型。
当处理 SWT 中的图像时,使用了图像、ImageData 和 ImageLoader 类。
ImageData 描述图像中的实际像素,使用 PaletteData 类来描述所使用的颜色值。ImageData 是图像的与设备和平台无关的描述。
ImageLoader 以不同的文件格式来装入和保存 ImageData。SWT 当前支持装入和保存 BMP(Windows 位图)、ICO(Windows 图标)、JPEG、GIF 和 PNG 图像格式。
图像是表示在绘图 API 中使用的图像的实际图形对象。为特定的显示创建图像。可以采用几种方法来创建图像:
不管您如何创建图像,您都要负责除去它。
用于在 SWT 中绘图的大多数图形对象在底层 OS 中分配资源,并且必须显式地释放这些对象。先前讨论的那些规则在此处也适用。如果使用构造函数来创建它,则应该释放它。如果是从其它地方获得它的,则不要释放它。
只要创建了对象,就在 OS 中分配图形对象,例如,图形上下文、字体、颜色和图像。您计划使用图形对象的方式确定创建它们的时间。
对于在整个应用程序中大量使用的图形对象,可以在创建小窗口时创建它们。这通常是针对颜色和字体。在其它情况下,更适合进行时创建图形对象。例如,可以在其中一个小窗口事件处理程序中创建图形上下文以便执行某些计算。
如果您正在实现定制小窗口,则通常在构造函数中分配图形对象(如果您始终要使用它们的话)。如果不是要一直使用它们,或者它们依赖于某些属性的状态,则可以进行时分配它们。
一旦已经分配了图形对象,就可以开始绘制了。始终应当在绘制侦听器内部进行绘制。很少情况下(特别是在实现定制小窗口时)要在绘制的同时响应其它某些事件。但是,这通常让人泄气。如果您认为需要在绘制的同时处理其它某些事件,则应该首先尝试使用 redraw() 方法,该方法将在 OS 中生成另一个绘制事件。在绘制方法外部进行绘图将使平台优化失效,并且可能会导致故障,这取决于事件队列中暂挂绘制的数目。
当接收到绘制事件时,将为您提供预先配置的 GC 用于在小窗口中绘图。不要释放此 GC!您未创建它。
在处理事件时(或之前)必须分配所有其它图形对象。以下是基于 org.eclipse.swt.examples.HelloWorld5 样本的代码片段。先前在创建小窗口时已分配了颜色为红色,因此,在此处可以使用它。
shell.addPaintListener(new PaintListener () { public void paintControl(PaintEvent event){ GC gc = event.gc; gc.setForeground(red); Rectangle rect = event.widget.getClientArea(); gc.drawRectangle(rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20); gc.drawString(resHello.getString("Hello_world"), rect.x + 20, rect.y + 20); } });
使用完您分配的每个图形对象时,必须释放它。
处理的时间取决于您是何时创建对象的。如果在创建小窗口的同时创建图形对象,则通常应该将除去侦听器添加到小窗口上,并在除去小窗口时除去图形。如果您在绘制进行时创建对象,则应该在完成绘图时除去它。
下面的代码片段说明绘制侦听器的稍作修改后的版本。在此示例中,它在绘图时分配和释放红色。
shell.addPaintListener(new PaintListener () { public void paintControl(PaintEvent event){ GC gc = event.gc; Color red = new Color(event.widget.getDisplay(), 0xFF, 0, 0); gc.setForeground(red); Rectangle rect = event.widget.getClientArea(); gc.drawRectangle(rect.x + 10, rect.y + 10, rect.width - 20, rect.height - 20); gc.drawString(resHello.getString("Hello_world"), rect.x + 20, rect.y + 20); red.dispose(); } });