You are on page 1of 9

Ejemplo de uso del GridBagLayout El GridBagLayout es uno de los Layout de java ms potentes, pero tambin es el que ms cuesta entender.

Vamos a construir una ventana en la que situamos determinados componentes (boton es) en determinadas posiciones usando el GridBagLayout. Puedes ver los fuentes d e ejemplo y applets funcionando pinchando en algunas de las imgenes que se ven du rante la explicacin. Concepto de layout A la hora de hacer "ventanitas" en java, un componente es cualquiera de los boto nes, etiquetas, listas, mens, etc que podemos colocar en la ventana. Hay determin ados componentes que no tienen un aspecto claro y que nicamente estn destinados a contener a los dems y se les llama contenedores. Por ejemplo, si una ventana cont iene dos botones, la ventana en si misma en otro componente java que recibe el n ombre de contenedor. Otro ejemplo, si te fijas en la barra de herramientas de tu navegador (echa el ojo un poco para arriba), vers que est llena de botones-iconos . La barra de herramientas en s misma es otro contenedor (aunque posiblemente no sea de java, sino del internet explorer o netscape). Cmo se distribuyen los botones dentro de la ventana?. Todos los contenedores en ja va tienen en su interior una clase, de nombre genrico "layout", que es la encarga da de distribuir los botones dentro del contenedor. Por ejemplo, la clase FlowLa yout se encarga de hacer que los botones vayan todos seguidos de izquierda a der echa, como sera el caso de tu barra de herramientas del navegador. El GridLayout los coloca en forma de matriz, etc, etc. Cualquier contenedor java tiene una clase layout por defecto, pero la podemos ca mbiar con el mtodo setLayout(). En java hay disponibles varios layout como los mencionados anteriormente, la may ora de ellos son muy sencillos de usar. Basta ponerlos y nos dan pocas opciones p ara configurar. Esto es vlido para ventanas sencillas con una distribucin de boton es no muy compleja. Por ejemplo, la barra de herramientas del navegador o el tec lado de una calculadora, en el que todos los botones sean del mismo tamao. Para ventanas ms complejas estos layout simples se quedan escasos. Java nos propo rciona un layout bastante potente, aunque bastante complejo de usar cuando no se comprende bien: el GridBagLayout. Este layout ser suficiente para hacer casi cua lquier distribucin de botones en una ventana, por compleja que parezca, pero debe mos entender bien su funcionamiento para que el resultado final se parezca a lo que queremos. En este tutorial vamos a hacer una ventanita con unos botones usando el GridBagL ayout y vamos a ver paso a paso cmo usarlo. La ventana que pretendemos obtener es la de la siguiente figura: Ventana que deseamos hacer con gridbaglayout Pincha la imagen para ver el applet que produce esta ventana y sus cdigo fuente. Juega a estirar la ventana para ver el comportamiento de los componentes en su i nterior. Tiene un rea de texto que ocupa casi toda la ventana. Un "Boton 1" en la parte su perior derecha, un "Boton 2" en la derecha hacia el medio, el "Boton 3" en la eq uina inferior izquierda, el "Boton 4" en la esquina inferior derecha y un campo de texto entre estos dos ltimos botones. Vamos a ello. Hacer una rejilla adecuada

El primer paso es dibujar la ventana que queremos (a los ms espabilados les basta r con hacerse una idea mental). Es importante dibujarla ms o menos estirada, para tener claro si los botones deben hacerse grandes o no. Por ejemplo, en la figura anterior, los botones deben mantener su tamao aunque estiremos la ventana, sin e mbargo el area de texto debe crecer con la ventaa y el campo de texto slo debe cr ecer horizontalmente. Luego, sobre el dibujo, hay que trazar unas lineas horizontales y verticales, pa ra tratar de delimitar una rejilla en la que iran colocados los botones. Para tr azar esta rejilla y que luego el cdigo no nos salga muy complicado conviene tener en cuenta lo siguiente: Debemos tratar de meter los componentes en las celdas. Cada componente debe ocupar una o ms celdas. Dos componentes no pueden ocupar la misma celda. No es necesario que las celdas de la rejilla sean todas del mismo tamao ni es necesario que un componente ocupe una celda completa. Para que no se lie el cdigo, conviene que el componente ocupe toda la celda, o bien que est centrado en la misma, o bien pegado al centro de uno de los bordes de la celda o a una esquina de la misma. Vaya, que no pongamos una celda enorme con un componente dentro a tres cuartos de la parte derecha y medio septimo de la parte de arriba. Un ejemplo de rejilla para nuestra ventana puede ser la de la siguiente figura: Ventana deseada con las lneas de filas y columnas. Vamos con las lneas verticales: La La La La primera en el borde izquierdo de la ventana. segunda entre el boton 3 y el campo de texto. tercera entre el campo de texto y el boton 4. ltima en el borde derecho de la ventana.

Estas lneas son casi obligadas, puesto que el boton 3, el campo de texto y el bot on 4 nos las limitan. No importa que una de ellas pase por enmedio del area de t exto, smplemente haremos que esta ocupe dos columnas. Estas lneas nos limitan tres columnas que hemos numerado como 0, 1 y 2. Vamos ahora con las lneas horizontale s. La primera por la parte de arriba de la ventana La segunda puede pasar por cualquier sitio entre el boton 1 y el boton 2. La tercera pasa justo por debajo del area de texto y por encima de boton 3, campo de texto y boton 4 La ltima por el borde inferior de la ventana. Como hemos dicho, la segunda puede pasar por cualquier lado entre los dos botone s. Para que no se nos complique el cdigo y segn dijimos arriba, cogiendo la segund a lnea pegando por arriba al botn 2 (como hemos hecho en el dibujo), ya tenemos al boton 2 ocupando la parte superior de su celda. Tambin podamos haberla pegado al botn 1, as el botn 2 estara ms o menos en el centro de su celda. Lo que complicara lue go el cdigo sera poner la lnea entre ambos botones, por lo que el boton 2 quedara a 1/3 de la parte superior de su celda. Podemos trazar ms lineas si queremos, como otras lineas horizontales que pasen po r debajo de boton 1 y boton 2, pero no son necesarias. Tampoco importara mucho ha cerlas ni se iba a complicar excesivamente el cdigo. Resumiendo, nuestro area de texto ocupa cuatro celdas, los botones una cada uno y el campo de texto otra. Boton 1 y 2 no ocupan toda la celda, pero estn en la pa

rte superior de la misma. Nuestra primera aproximacin Vamos a hacer nuestro primer cdigo para obtener la ventana. Nuestra ventana ser un JFrame, as que hacemos una clase que herede de JFrame y le ponemos el GridBagLay out. class Ventana extends JFrame { public Ventana() { super ("Ejemplo 1"); // El ttulo this.getContentPane().setLayout (new GridBagLayout()); // Le ponemos el Gr idBagLayout ... } } Lo del getContentPane() es porque en realidad la ventana no es el contenedor, si no un componente que lleva internamente la ventana y que se puede obtener a travs de este mtodo. Es a este componente al que debemos aadirle el layout y los compon entes (botoncitos y dems). Ahora debemos empezar a aadir componentes. Tenemos por un lado el mtodo add() con un slo parmetro. JTextArea areaTexto = new JTextArea("Area texto"); this.getContentPane().add (areaTexto); Esta llamada aade el rea de texto, dejando al GridBagLayout total libertad para de cidir dnde y cmo ponerlo. No es lo que queremos. Necesitamos el mtodo add() que adm ite un segundo parmetro. Este segundo parmetro le indica al layout dnde y cmo coloca r el componente. El segundo parmetro es un Object, lo que quiere decir que podria mos meter cualquier cosa. Evidentemente esto no es asi, debemos meter algo que e l layout entienda. Cada layout entiende su propio segundo parmetro. El GridBagLay out admite como segundo parmetro un GridBagConstraints. GridBagConstraints en una clase en cuyos atributos se guarda informacin de cmo y dn de aadir el componente. De momento vamos a contemplar slo cuatro de estos atributo s: GridBagConstraints.gridx nos dice la posicin x del componente, es decir, el nm ero de columna en la que est el componente, siendo la columna 0 la primera column a de la izquierda. Si el componente ocupa varias columnas (como nuestra rea de te xto), debemos indicar la columna en la que est la esquina superior izquierda del componente. GridBagConstraints.gridy nos dice la posicin y del componente, es decir, el nm ero de fila en la que est el componente, siendo la fila 0 la primera fila de la p arte de arriba. Si el componente ocupa varias filas (como nuestra rea de texto), debemos indicar la fila en la que est la esquina superior izquierda del component e. GridBagConstraints.gridwidth nos dice cuntas celdas en horizontal debe ocupar el componente. El ancho del componente. GridBagConstraints.gridheight nos dice cuantas celdas en vertical debe ocupa r el componente. El alto del componente. Con esto podemos aadir nuestra rea de texto JTextArea areaTexto = new JTextArea ("Area texto"); GridBagConstraints constraints = new GridBagConstraints();

constraints.gridx = 0; // El rea de texto empieza en la columna cero. constraints.gridy = 0; // El rea de texto empieza en la fila cero constraints.gridwidth = 2; // El rea de texto ocupa dos columnas. constraints.gridheight = 2; // El rea de texto ocupa 2 filas. this.getContentPane().add (areaTexto, constraints); En realidad gridwith y gridheight admite tambin determinadas constantes que hacen que el componente se estire hasta el final del contenedor, ocupando todas las c olumnas o filas libres o hasta que encuentre otro componente. No vamos a usar es as constantes (estn definidas en GridBagConstraints) y simplemente hemos puesto e l nmero de filas y columnas (2 en ambos casos) que queremos que ocupe. Los siguientes elementos tienen todos un gridwidth y gridheight de 1, puesto que ocupan una fila y columna. Las posiciones son las siguientes: JButton boton1 = new JButton ("Boton 1"); constraints.gridx = 2; constraints.gridy = 0; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton1, constraints); JButton boton2 = new JButton ("Boton 2"); constraints.gridx = 2; constraints.gridy = 1; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton2, constraints); JButton boton3 = new JButton ("Boton 3"); constraints.gridx = 0; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton3, constraints); JButton boton4 = new JButton ("Boton 4"); constraints.gridx = 2; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton4, constraints); JTextField campoTexto = new JTextField ("Campo texto"); constraints.gridx = 1; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (campoTexto, constraints); Hay un detalle importante a tener en cuenta. Slo hemos hecho un new de GridBagCon straints, por lo que todos ellos comparten la misma instancia de ese objeto. Hay que tener en cuenta que si cambiamos uno de los atributos para un componente, d ebemos restaurarlo luego para el siguiente. Por ejemplo, para el area de texto p usimos gridwidth a 2. Para el siguiente componente (el botn1), debemo volver a po ner esta valor a 1. Por ello es acosejable poner siempre todos los atributos. Otra opcin es hacer un new GridBagConstraints para cada componente (claramente menos eficiente) o final mente la que he seguido en el cdigo de ejemplo, ser muy cuidadoso e ir restaurand

o valores segn se van cambiando. Si ejecutamos lo que tenemos hasta ahora y estiramos un poco la ventana resultan te nos sale lo de la siguiente figura: applet de ejemplo Pincha la figura para ver el applet que produce esta ventana y sus cdigo fuente. Bueno, no se parece mucho a lo que queramos. Se ha quedado todo en el centro de l a ventana y el area de texto es bastante canija. Qu ha pasado? Estirar las filas y las columnas Lo que ha pasado es que slo le hemos dicho al GridBagLayout dnde colocar los compo nentes y eso lo ha hecho bien. Cada componente est donde debe. Lo que pasa es que no le hemos dicho nada de cmo estirar las filas y columnas, as que ha hecho lo qu e hace por defecto: Cada fila y columna es del tamao mnimo necesario para albergar sus componentes y estn centradas dentro de la ventana. En la siguiente figura ve mos como estn nuestras filas y columnas: applet de ejemplo gridbaglayout Las filas son de la altura justa para contener a los botones. Las columnas tambin . El rea de texto que ocupa cuatro celdas se ha situado en el medio de ellas y le sobra un montn de espacio. El siguiente paso a dar consiste en decir cmo se deben estirar las filas columnas . Si comparamos con la figura en las que marcamos inicialmente las filas y colum nas, vemos que las dos primeras filas deben ser ms anchas, la tercera fila ya est bien de ancho. En cuanto a las columnas, la segunda es la que debe estirarse, la primera y tercera estn bien. Para estirar filas y columnas, dentro del GridBagConstraints tenemos los campos weigthx y weigthy. El primero indica cmo estirar las columnas. El segundo las fil as. Aqui vamos a contar una forma sencilla de usar estos campos que nos servir pa ra la mayora de los casos. En realidad podramos sacarle bastante ms jugo. A estos campos debemos darles el valor 0.0 (que es el valor por defecto) si no q ueremos que la fila o columna se estire. Este es el caso para la primera y terce ra columna, as como para la tercera fila. Debemos dar el valor 1.0 a las filas o columnas que queremos que se estiren hasta completar toda la ventana. Es el caso de las dos primeras filas y de la columna del medio. Hay dos detalles con estos campos. El primero es que widthy afecta a una fila co mpleta, no solo a un componente. Por ello, cada vez que aadamos un componente a e sa fila, debemos dar a widthy el mismo valor (o 0.0 o 1.0). Lo mismo pasa con wi dthx y las columnas. El segundo detalle es el que comentamos antes, slo estamos u sando una instancia de GridBagConstraints, asi que despus de poner uno de estos c ampos a 1.0 y aadir un componente, debemos volver a ponerlo a 0.0 para el siguien te (suponiendo que sea eso lo que necesita). El cdigo ahora, aadiendo estos dos campos, quedara as: JTextArea cajaTexto = new JTextArea("Area texto"); constraints.gridx = 0; // Columna 0. No necesita estirarse, no ponemos weightx constraints.gridy = 0; // Fila 0. Necesita estirarse, hay que poner weighty constraints.gridwidth = 2; constraints.gridheight = 2; constraints.weighty = 1.0; // La fila 0 debe estirarse, le ponemos un 1.0 this.getContentPane().add (cajaTexto, constraints); constraints.weighty = 0.0; // Restauramos al valor por defecto, para no afectar

a los siguientes componentes. JButton boton1 = new JButton ("Boton 1"); constraints.gridx = 2; // Columna 2. No necesita estirarse, no ponemos weightx constraints.gridy = 0; // Fila 0. Necesita estirarse, hay que poner weighty constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weighty = 1.0; /* La fila 0 debe estirarse, le ponemos un 1.0. Ya lo hicimos en el area de texto, pero aqu debemos ser coherentes y poner lo mismo.*/ this.getContentPane().add (boton1, constraints); constraints.weighty = 0.0; // Restauramos al valor por defecto, para no afectar a los siguientes componentes. JButton boton2 = new JButton ("Boton 2"); constraints.gridx = 2; // Columna 2, no necesita estirarse, no ponemos weigthx constraints.gridy = 1; // Fila 1, necesita estirarse, hay que poner weigthy constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weighty = 1.0; // La fila 1 debe estirarse, le ponemos 1.0 this.getContentPane().add (boton2, constraints); constraints.weighty = 0.0; // Restauramos el valor por defecto. JButton boton3 = new JButton ("Boton 3"); constraints.gridx = 0; // Columna 0, no necesita estirarse, no ponemos weigthx constraints.gridy = 2; // Fila 2, no necesita estirarse, no ponemos weigthy constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton3, constraints); JButton boton4 = new JButton ("Boton 4"); constraints.gridx = 2; // Columna 2, no necesita estirarse, no ponemos weightx constraints.gridy = 2; // Fila 2, no necesita estirarse, no ponemos weigthy constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton4, constraints); JTextField campoTexto = new JTextField ("Campo texto"); constraints.gridx = 1; // Columna 1, debe estirarse, le ponemos el weigthx constraints.gridy = 2; // Fila 2, no necesita estirarse, no ponemos weigthy constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1.0; // La columna 1 debe estirarse, ponemos el 1.0 en wei gthx this.getContentPane().add (campoTexto, constraints); /* Puesto que es el ltimo componente, no restauramos el valor por defecto. Si ms a delante aadimos ms componentes, seguro que pagamos cara nuestra osada.*/ Bueno, vamos a ejecutar nuestro programa, estirar la ventana y a ver qu sale. Sal e lo de la siguiente figura, que tampoco es lo que queremos. applet de ejemplo gridbaglayout Pincha la figura para ver el applet que produce esta ventana y sus cdigo fuente. Qu es lo que ha pasado ahora?. Como dice un viejo dicho de informtica, el ordenador se empea en hacer lo que le decimos y no lo que queremos. Le hemos dicho que est ire las filas y columnas y es lo que ha hecho, pero como no le hemos dicho nada sobre los componentes, no los ha estirado en absoluto. Estirar los componentes Si pintamos sobre la ventana las rayas que delimtan filas y columnas, vemos que

efectivamente se han ensanchado las que hemos dicho applet de ejmplo gridgablayout pero los componentes siguen con su tamao original y en el centro de las celdas qu e tienen asignadas. El area de texto sigue igual, en el centro de sus cuatro cel das, los botones 1 y 2 se han centrado en sus celdas y lo mismo le pasa al campo de texto. Lo siguiente que tenemos que hacer es decir qu componentes deben estirarse (el ar ea de texto y el campo de texto para nuestro ejemplo). Para aquellos componentes que no deben estirarse, podemos indicar en qu parte de la celda queremos que se situen (caso del boton 1 y boton 2). Para hacer que un componente se estire, tenemos el atributo fill del GridBagCons traints. Este puede tomar los siguientes valores: GridBagConstraints.NONE para que no se estire en ningn sentido, es la opcin po r defecto. GridBagConstraints.VERTICAL para que se estire slo en vertical GridBagConstraints.HORIZONTAL para que se estire slo en horizontal. GridBagConstraints.BOTH para que se estire en ambas dimensiones Si el componente no se estira en alguna direccin, podemos decirle por medio de an chor en GridBagConstraints qu posicin queremos que ocupe. Las posibilidades son GridBagConstraints.CENTER para que el componente ocupe el centro de la celda . Es la opcin por defecto GridBagConstraints.NORTH para que se pegue a la parte superior, centrado en la misma. GridBagConstraints.NORTHEAST para que se pegue a la esquina superior derecha . ... (qu pereza me da escribir todos los puntos cardinales ...) GridBagConstraints.WEST para que se pegue al lado izquierdo, centrado en ese lado. GridBagConstraints.NORTHWEST para que se pegue a la esquina superior izquier da. Igual que antes, estamos usando una nica instancia de GridBagConstraints, por lo que si al aadir un componente cambiamos una opcin, debemos tenerlo en cuenta para el siguiente. Bueno, pues bsicamente nos queda decirle al area de texto de se ensanche en todos los sentidos, al campo de texto que se ensanche en horizontal y a los botones 1 y 2 que ocupen la posicion NORTH de su celda. El cdigo sera el siguiente: JTextArea cajaTexto = new JTextArea("Area texto"); constraints.gridx = 0; constraints.gridy = 0; constraints.gridwidth = 2; constraints.gridheight = 2; // El area de texto debe estirarse en ambos sentidos. Ponemos el campo fill. constraints.fill = GridBagConstraints.BOTH; constraints.weighty = 1.0; this.getContentPane().add (cajaTexto, constraints); constraints.weighty = 0.0; JButton boton1 = new JButton ("Boton 1"); constraints.gridx = 2; constraints.gridy = 0;

constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weighty = 1.0; // El botn 1 debe ocupar la posicin NORTH de su celda constraints.anchor = GridBagConstraints.NORTH; // El botn 1 no debe estirarse. Habamos cambiado este valor en el // area de texto, asi que lo restauramos. constraints.fill = GridBagConstraints.NONE; this.getContentPane().add (boton1, constraints); // Restauramos valores por defecto constraints.anchor = GridBagConstraints.CENTER; constraints.weighty = 0.0; JButton boton2 = new JButton ("Boton 2"); constraints.gridx = 2; constraints.gridy = 1; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weighty = 1.0; // El boton 2 debe ocupar la posicin NORTH de su celda. constraints.anchor = GridBagConstraints.NORTH; this.getContentPane().add (boton2, constraints); // Restauramos valores por defecto. constraints.weighty = 0.0; constraints.anchor = GridBagConstraints.CENTER; JButton boton3 = new JButton ("Boton 3"); constraints.gridx = 0; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton3, constraints); JButton boton4 = new JButton ("Boton 4"); constraints.gridx = 2; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; this.getContentPane().add (boton4, constraints); JTextField campoTexto = new JTextField ("Campo texto"); constraints.gridx = 1; constraints.gridy = 2; constraints.gridwidth = 1; constraints.gridheight = 1; constraints.weightx = 1.0; // El campo de texto debe estirarse slo en horizontal. constraints.fill = GridBagConstraints.HORIZONTAL; this.getContentPane().add (campoTexto, constraints); Bueno, ejecutamos esto, estiramos la ventana, y Eureka!. Sale lo que queramos al p rincipio. (No repito la figura, sube un poco y chale un ojo si no la recuerdas). Algunos comentarios finales Con esto ya deberamos ser capaces de situar los componentes en nuestra ventana en la mayora de las ocasiones. El GridBagConstraints nos permite ms cosas, de las qu e sealo aqu un par de ellas, por si alguien quiere indagar un poco ms. Los camos weightx y weighty, como hemos visto, hace que se estiren las filas y c olumnas. Hemos puesto 0.0 para las que no se estiran y 1.0 para las que s. En rea

lidad cada fila o columna se estira en proporcin al valor de este campo respecto a los dems. Por ejemplo, si a la columna 1 le ponemos weightx=1.0 y a la 2 le pon emos weightx=0.5, ambas se estiraran , pero la primera el doble que la segunda. Hay campos insets, ipadx e ipady que permiten fijar mrgenes entre los componentes , de forma que no queden pegados entre s. Puedes ver los fuentes y applets funcionando con las tres ventanas que hemos con seguido pinchando en las imgenes que hemos ido viendo.

You might also like