SWT proporciona un motor de gráficos para dibujar gráficos y visualizar imágenes en los widgets. Podrá obtener excelentes resultados sin ni siquiera programar la interfaz de gráficos, porque los widgets manejan automáticamente el dibujo de iconos, texto y otros datos. Sin embargo, si la aplicación visualiza gráficos personalizados o si el usuario está implementando un widget de dibujo personalizado, deberá entender cómo funcionan algunos objetos de dibujo básicos de SWT.
El contexto de gráficos, GC, es el punto focal del soporte de gráficos de SWT. Su API describe todas las posibilidades de dibujo de SWT.
Se puede utilizar un GC para dibujar en un control (el caso más habitual) o en una imagen, pantalla o impresora. Cuando se dibuja en un control, se utiliza el GC suministrado en el evento de pintura del control. Cuando se dibuja en una imagen, pantalla o impresora, debe crear un GC configurado para la misma y desechar el GC cuando termine de utilizarlo.
Una vez que haya obtenido un GC, puede establecer sus atributos como, por ejemplo, el color, el ancho de línea y el font, que controlan el aspecto de los gráficos dibujados en el GC.
El manual de consulta de las API de GC describe el conjunto completo de funciones gráficas.
Las clases Font y FontData permiten manipular los fonts de SWT.
FontData describe las características de un font. Puede crear un FontData especificando un nombre, un estilo y un tamaño de font. FontData incluye una API para consultar estos atributos. Dado que FontData no asigna recursos de OS, no es necesario que se deshaga de ella.
La clase Font es el objeto gráfico propiamente dicho que representa un font utilizado en la API de dibujo. Para crear un Font para Display, deben especificarse los valores de Display y FontData del font que desea. También puede consultar Font para obtener su FontData.
Cuando termine de utilizar un Font asignado, debe desecharlo.
Los colores son parecidos a los fonts. Para crear un Color para Display, especifique los valores RGB del color deseado. Cuando haya terminado de utilizar un color asignado, debe desecharlo.
El método de Display getSystemColor(int)
permite consultar los
colores predefinidos del sistema para la plataforma de OS.
No debe liberar los colores obtenidos mediante esta técnica.
El modelo del color se trata detalladamente en el artículo Modelo de color de SWT.
Las clases Image, ImageData e ImageLoader sirven para manipular las imágenes de SWT.
ImageData describe los píxeles reales de la imagen utilizando la clase PaletteData para describir los valores de colores utilizados. ImageData es una descripción de una imagen independiente del dispositivo y de la plataforma.
ImageLoader carga y guarda ImageData en formatos de archivo diferentes. SWT da soporte actualmente a la carga y guardado de formatos de imagen tales como BMP (Bitmap de Windows), ICO (Icono de Windows), JPEG, GIF y PNG.
Image es el objeto gráfico propiamente dicho que representa la imagen que se utiliza en la API de dibujo. Debe crearse una imagen para cada Display individual. Las imágenes se pueden crear de varias maneras:
Independientemente de cómo haya creado Image, el usuario es responsable de desecharla.
La mayoría de los objetos gráficos utilizados para dibujar en SWT asignan recursos del OS subyacente y deben liberarse explícitamente. Aquí se aplica la misma regla que se ha descrito anteriormente. Si los crea utilizando un constructor, debe liberarlos. Si accede a ellos desde otro lugar, no debe liberarlos.
Los objetos gráficos, como son los contextos de gráficos, los fonts, los colores y las imágenes, se asignan en el OS en cuanto se crean. La manera en la que piensa utilizar los objetos gráficos determina el momento en que debe crearlos.
Si va a utilizar objetos gráficos de manera intensiva en la aplicación, puede crearlos en el momento de crear los widgets. Esto suele hacerse en el caso de los colores y los fonts. En los demás casos, es más adecuado crearlos sobre la marcha. Por ejemplo, podría crear un contexto de gráficos en uno de los manejadores de eventos de widget para efectuar algunos cálculos.
Si está implementando un widget personalizado, lo normal será que asigne los objetos gráficos en el constructor si los va a utilizar siempre. Si no los va a utilizar siempre o si dependen del estado de algunos atributos, puede asignarlos sobre la marcha.
Una vez que haya asignados los objetos gráficos, estará listo para pintarlos. Siempre debe realizar la actividad de pintura dentro de un escuchador de pintura. Existen muy pocos casos, particularmente al implementar widgets personalizados, en que la pintura se realiza mientras se responde a otro evento. Habitualmente, eso no debe hacerse. Si piensa que necesita pintar mientras esté manejando otro evento, primero debe intentar utilizar el método redraw, que generará otro evento de pintura en el OS. Si se dibuja sin utilizar el método de pintura, no se podrán efectuar optimizaciones de la plataforma y podrían producirse errores en función del número de pinturas pendientes que haya en la cola de eventos.
Cuando reciba un evento de pintura, se le suministrará un GC preconfigurado para dibujar en el widget. No libere este GC. Ello se debe a que no lo creó.
Los otros objetos gráficos se deben asignar mientras maneja el evento (o previamente). A continuación, se muestra un fragmento de código basado en el ejemplo org.eclipse.swt.examples.HelloWorld5. El color rojo se asignó previamente al crear el widget, por lo que puede utilizarse aquí.
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); } });
Todos los objetos gráficos que se han asignado deben liberarse cuando ya no se necesiten.
El momento de la eliminación depende de cuándo se creó el objeto. Si crea un objeto gráfico mientras está creando el widget, deberá en general añadir un escuchador de eliminación al widget y desechar los gráficos cuando se deseche el widget. Si crea un objeto sobre la marcha mientras esté pintando, deberá desecharlo cuando haya terminado de pintarlo.
El siguiente fragmento de código muestra una versión ligeramente modificada de nuestro escuchador de pintura. En este ejemplo, se asigna y libera el color rojo mientras se está pintando.
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(); } });