domingo, 31 de agosto de 2014

Capturar un Component de Swing/AWT (renderizar a una imagen)

Introducción


A veces, programáticamente interesa guardar una imagen de la apariencia visual (captura) de un progrma Java. Una posibilidad muy sencilla es utilizar el método:

Pero... ¿y si lo que se desea capturar es solamente un componente?

¿Y si se desea capturar un componente que no cabe en pantalla? Por ejemplo, un componente que esté envuelto en un JScrollPane, todas las filas de una tabla o una ventana sobredimensionada.

¿Y si se desea capturar una componente que está parcialmente o totalmente fuera de la pantalla? Por ejemplo, una ventana que se ha desplazado parcialmente fuera de la pantalla.

Solución


La clase Component de Java tiene el método:

La clase BufferedImage tiene el método:

La clave está en combinar ambos métodos:
  1. Construir una imagen del tamaño del componente.
  2. Pintar el componente sobre el contexto gráfico de la imagen.
Con la imagen luego se pueden hacer procesos posteriores como guardarla en un fichero.

Este mecanismo se puede utilizar con cualquier Component, incluidas las ventanas y los diálogos, incluso aunque no estén total o parcialmente en la pantalla.

Ejemplo


En el siguiente enlace está la pequeña clase CaptureTest que permite guardar cualquier componente en un fichero PNG (Portable Network Graphics):

El método CaptureTest#capture(Component, Color) realiza la tarea descrita en este artículo, incluyendo algunos detalles técnicos como el color de fondo para componentes con partes transparentes o el ajuste del tamaño de ventanas descontando las decoraciones (la barrita con los botones de maximizar, minimizar, etc. que incluye el manejador de ventanas).

Al probarla, hay que tener en cuenta que los ficheros con las capturas se intentan crear en el directorio desde donde se invoca la máquina virtual Java.

Conclusión


Este artículo demuestra un uso muy sencillo y práctico de algunas funcionalidades disponibles en la la API de Swing/AWT y referencia la clase CaptureTest, cuyo código se puede utilizar para realizar la tarea descrita en él.

Enlaces


Enlaces de interés relacionados con este artículo:

(Actualizado 31/08/2014)

2 comentarios:

  1. Nunca había pensado en combinar esos métodos. Interesante.

    ResponderEliminar
    Respuestas
    1. A veces hay soluciones simples perdidas en medio de las APIs. Gracias por comentar.

      Eliminar