## Crear un Controlador de Distribución Personalizado

> Nota: Antes de empezar a crear un controlador de disposición personalizado, asegurate de que no existe ningún controlador que trabaje de la forma apropiada. En particular, GridBagLayout y BoxLayout son lo suficientemente flexibles para trabajar en muchos casos. También puedes encontrar controladores de distribución desde otras fuentes, como Internet. Finalmente, puedes simplificar la distribución agrupando los componentes en contenedores como en un panel invisible

Para crear un controlador de distribución personalizado, debemos crear una clase que implemente el interface LayoutManager. Podemos implementando directamente o implementar su subinterface, LayoutManager2.

Todo controlador de distribución debe implementar al menos estos cinco métodos, que son requeridos por el interface LayoutManager:

void addLayoutComponent(String, Component)
  Llamado por los métodos add de Container. Los controladores de distribución que no asocian cadenas con sus componentes generalmente no hacen nada en este métodos.

void removeLayoutComponent(Component)
  Llamado por los métodos remove y removeAll de Container. Los controladores de distribución no hacen nada en este metodo, en su lugar le preguntan por sus componentes al contenedor usando el método getComponents de Container.

Dimension preferredLayoutSize(Container)
  Llamado por el método getPreferredSize de Container que a su vez es llamado bajo una gran variedad de circunstancias. Este método debería calcular y devolver el tamaño ideal del contenedor, asumiendo que todos sus componentes serán de sus tamaños preferidos. Este método debe tener en cuenta los bordes internos del contenedor que son devueltos por el método getInsets.

Dimension minimumLayoutSize(Container)
  Llamado por el método getMinimumSize de Container, que a su vez es llamado bajo una gran variedad de circunstancias. Este método debería calcular y devolver el tamaño mínimo del contenedor, asumiendo que todos sus componentes serán de sus tamaños mínimos. Este método debe tener en cuenta los bordes internos del contenedor que son devueltos por el método getInsets.

void layoutContainer(Container)
  Llamado cuando el contenedor se muestra por primera vez, y cada vez que cambie su tamaño. Este método realmente no dibuja componentes, sólo invoca a los métodos resize, move, y reshape de cada componente, para seleccionar su tamaño y posición. Este método debe tener en cuenta los bordes internos del contenedor que son devueltos por el método getInsets. No podemos asumir que se llamara a preferredLayoutSize o minimumLayoutSize antes de llamar a layoutContainer.

Además de la implementación de los cinco métodos anteriores, los controladores de distribución generalmente implementan un constructor público y el método toString.

Si deseamos soportar restricciones de componnetes, tamaños máximos o alineamiento, entonces nuestro controlador de distribución debería implementar el interface LayoutManager2. Este interface añade cinco métodos a los requeridos por LayoutManager:

- addLayoutComponent(Component, Object)
- getLayoutAlignmentX(Container)
- getLayoutAlignmentY(Container)
- invalidateLayout(Container)
- maximumLayoutSize(Container)

Para más información sobre estos métodos, puedes ver LayoutManager2 API documentation. También puedes ver el código fuente de BoxLayout, para ver como implementa el interface LayoutManager2.

Cuando se implementa un controlador de distribución, podríamos queres usan un objeto SizeRequirements para ayudarnos a determinar el tamaño y posición de los componentes. Puedes ver el código fuente de BoxLayout para ver un ejemplo de uso de SizeRequirements.

Aquí tienes el código fuente de DiagonalLayout, un controlador de distribución personalizado que distribuye sus componentes diagonalmente, de izquierda a derecha, con un componente por fila. Aquí tenemos a DiagonalLayout en acción:

Esta es una imagen del GUI del Applet. Para ejecutarlo pulsa sobre ella y el applet aparecerá en una nueva ventana del navegador.

Ozito