s Gráficos

Gráficos

SWT proporciona un sólido 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.

Contexto de gráficos

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 dicha imagen, pantalla o impresora, y desechar el GC cuando ya no lo necesite).

En cuanto obtenga un GC, podrá establecer sus atributos, como el color, el ancho de línea y el font, que controlan el aspecto del dibujo de los gráficos en el GC.

El manual de consulta de las API de GC describe todas las funciones gráficas.

Fonts

Las clases Font y FontData permiten manipular los fonts de SWT.

FontData describe las características de un font. Puede crear una clase FontData especificando un nombre, un estilo y un tamaño de font. FontData incluye la API para consultar estos atributos. Puesto que la clase FontData no asigna ningún recurso de OS, no hace falta que la deseche.

La clase Font es el objeto gráfico real que representa un font que se utiliza en la API de dibujo. Puede crear una clase Font para un widget Display especificando el objeto Display y el objeto FontData del font que desea. También puede consultar un Font para obtener su FontData.

Debe desechar una clase Font asignada cuando haya terminado de utilizarla.

Colores

Los colores son parecidos a los fonts. Debe crear un Color para un Display especificando los valores RGB (rojo, amarillo y azul) para el color deseado. Cuando haya terminado de utilizar un color asignado, debe desecharlo.

El método getSystemColor de Display le 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.

Imágenes

Las clases Image, ImageData e ImageLoader sirven para manipular las imágenes de SWT.

ImageData describe los pixels reales de la imagen utilizando la clase PaletteData para describir los valores de los colores utilizados. ImageData es una descripción de la imagen independiente de dispositivo y de plataforma.

ImageLoader carga y guarda ImageData en formatos de archivo distintos. SWT soporta actualmente las operaciones de cargar y guardar formatos de imágenes BMP (Bitmap de Windows), ICO (Icono de Windows), JPEG, GIF y PNG.

La clase Image es el objeto gráfico real que representa la imagen que se utiliza en la API de dibujo. Debe crear una imagen para cada Display concreto. Las imágenes se pueden crear de varias maneras:

Independientemente de cómo haya creado la clase Image, el usuario es quien deberá desecharla.

Ciclo vital de los objetos gráficos

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.

Creación

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.

Pintura

Una vez asignados los objetos gráficos, ya podrá pintarlos. La pintura siempre debe llevarse a cabo en 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);
      }
   });

Eliminación

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();
      }
   });

Copyright IBM Corporation y otros 2000, 2003.