Alfonso Marín López

Blog personal de un programador

Layout y resize en GWT

| 0 comments

El sistema de layouts de GWT cambio en la versión 2.0. Desde entonces se usan las interfaces RequiereResize y ProvidesResize. El mecanismo se usa en cascada y debemos tener en cuanta varias cosas:

  • Partir desde el RootLayoutPanel, que ya implementa RequiereResize y ProvidesResize.
  • Modo estándar: hay que poner en el html la siguiente instrucción <!DOCTYPE html>
  • No romper la cadena, si tenemos una estructura un poco compleja y el cambio de tamaño afecta a toda la cadena, todas las clases intervinientes deben implementarlo, si nos dejamos una ya no funcionara.

Tenemos dos tipos de clases o paneles, los que son layout e implementan la interfaz RequiereResize y los que no.

Entre los que los tienes son las clases nuevas como RootLayoutPanel, y todos los paneles que contengan la palabra layout. Aunque el problema viene con los paneles que utilizan las tablas como estructura interna. Algunos elementos de html como los divs, dependiendo de los navegadores, interpretan el 100% de forma diferente, por ejemplo, si pones un div en una celda que mide 100px de ancho y tiene un borde de 1px y padding de 5px, el div cogerá y pondrá que mide 112px de ancho más su propio bode, padding y magen, con lo que se sale el div de la celda. Y resulta difícil arreglarlo salvo implementando el onResize y teniendo en cuenta todos estos margenes. Aunque poco se puede hacer por el momento para sustituir el HorizontalPanel y el VerticalPanel.

Si se quiere implementar esta interfaz solo hay que implementar onRiseze() modificando los tamaños que queramos

En el caso de los Composites podemos hacerlo de dos maneras

  • ResizeComposite: Si extendemos de esta clase, ya viene implementada onResize() y lo único que hace es comprobar que el objeto que tiene como hijo sea RequiereResize y llama a su onResize(), pero el hijo debe ser un objeto RequiereResize, si no dará una excepción nada mas ponerlo en marcha.
  • Implementar RequiereResize: esta es lo mismo que lo anterior pero seremos nosotros quienes implementemos el método onResize() y no tendremos la restricción de que el hijo sea RequiereResize, pudiendo poner cualquier widget.

Después tenemos la interfaz ProvidesResize que solo indica que la clase que la implementa propaga sobre sus hijos el onResize(), es decir, que si alguna de vuestras clases o componentes en su método onResize() lo propaga por todos sus hijos, entonces debería implementar esta interfaz. Aunque a efectos prácticos funciona igual, es más aclaratoria en la documentación.

Esto es lo que he aprendido de su uso en este último año, que ha sido muy intenso, pero como siempre acepto y agradezco cualquier corrección o aportación.

NOTA: En ocasiones el calculo del tamaño de un widget lleva su tiempo, y pueden haber discrepancias con respecto a lo pintado. La solución que he encontrado por internet es la de poner un Timer en el onResize de pocos milisegundos para darle tiempo al recalculo.

new Timer() {

@Override

public void run() {

int width = ResizeContainer.this.getOffsetWidth();

}

}.schedule(100);

Aunque no resulte muy elegante.