Lenguaje de Prgramacion II
LAYOUTS Los layout managers o manejadores de composición, en traducción literal, ayudan a adaptar los diversos Componentes que se desean incorporar a un Panel, es decir, especifican la apariencia que tendrán los Componentes a la hora de colocarlos sobre un Contenedor. Java dispone de varios, en la actual versión, tal como se muestra en la imagen:
¿Por qué Java proporciona estos esquemas predefinidos de disposición de componentes? La razón es simple: imaginemos que deseamos agrupar objetos de distinto tamaño en celdas de una rejilla virtual: si confiados en nuestro conocimiento de un sistema gráfico determinado, codificamos a mano tal disposición, deberemos preveer el redimensionamiento del applet, su repintado cuando sea cubierto por otra ventana, etc., además de todas las cuestiones relacionadas con un posible cambio de plataforma (uno nunca sabe a donde van a ir a parar los propios hijos, o los applets). Sigamos imaginando, ahora, que un hábil equipo de desarrollo ha previsto las disposiciones gráficas más usadas y ha creado un gestor para cada una de tales configuraciones, que se ocupará, de forma transparente para nosotros, de todas esas cuitas de formatos. Bien, pues estos gestores son instancias de las distintas clases ager y que se utilizan en el applet que genera la figura siguiente, donde se muestran los diferentes tipos de layouts que proporciona el AWT.
Profesor: Quiñones Nieto, Yamil
Página 1
Lenguaje de Prgramacion II
En el applet que genera la figura siguiente, se utilizan los diferentes tipos de layouts que proporciona el AWT.
El ejemplo AwtGui.java, ilustra el uso de paneles, listas, barras de desplazamiento, botones, selectores, campos de texto, áreas de texto y varios tipos de layouts. En el tratamiento de los Layouts se utiliza un método de validación, de forma que los Componentes son marcados como no válidos cuando un cambio de estado afecta a la geometría o cuando el Contenedor tiene un hijo incorporado o eliminado. La validación se realiza automáticamente cuando se llama a pack() o show(). Los Componentes visibles marcados como no válidos no se validan automáticamente.
1.‐ FlowLayout Es el más simple y el que se utiliza por defecto en todos los Paneles si no se fuerza el uso de alguno de los otros. Los Componentes añadidos a un Panel con FlowLayout se encadenan en forma de lista. La cadena es horizontal, de izquierda a derecha, y se puede seleccionar el espaciado entre cada Componente. Por ejemplo, podemos poner un grupo de botones con la composición por defecto que proporciona FlowLayout:
Profesor: Quiñones Nieto, Yamil
Página 2
Lenguaje de Prgramacion II
Codigo Fuente import java.awt.*; import java.applet.Applet; // Demostracion de uso del FlowLayout public class AwtFlow extends Applet { Button boton1,boton2,boton3; public void init() { // Simplemente a¤adimos tres botones al Applet, y como el // FlowLayout es el que se usa por defecto, ni nos // molestamos en indicar que ese es el que queremos boton1 = new Button( "Aceptar" ); boton2 = new Button( "Abrir" ); boton3 = new Button( "Cerrar" ); add( boton1 ); add( boton2 ); add( boton3 ); } } import javax.swing.JFrame; import javax.swing.*; /** * * @author usuario */ public class FlowLayout extends JFrame{ JButton boton; public FlowLayout() { setTitle("El titulo"); setDefaultCloseOperation(EXIT_ON_CLOSE); setLocationRelativeTo(null);
Profesor: Quiñones Nieto, Yamil
Página 3
Lenguaje de Prgramacion II
setLayout(new java.awt.BorderLayout()); setSize(300,300); //setIconImage(new ImageIcon("c:\\editpaste.png").getImage()); boton=new JButton("Soy un boton"); boton.setBounds(20, 20, 160, 20);//x,y,ancho,largo getContentPane().add(boton); setVisible(true); } public static void main(String args[]) { j_frame f= new j_frame(); } }
2.‐ BorderLayout La composición BorderLayout (de borde) proporciona un esquema más complejo de colocación de los Componentes en un panel. La composición utiliza cinco zonas para colocar los Componentes sobre ellas: Norte, Sur, Este, Oeste y Centro. Es el layout o composición que se utilizan por defecto Frame y Dialog. El Norte ocupa la parte superior del panel, el Este ocupa el lado derecho, Sur la zona inferior y Oeste el lado izquierdo. Centro representa el resto que queda, una vez que se hayan rellenado las otras cuatro partes. Con BorderLayout se podrían representar botones de dirección:
Profesor: Quiñones Nieto, Yamil
Página 4
Lenguaje de Prgramacion II
import java.awt.*; import java.applet.Applet; // Clase para demostrar la apariencia del BorderLayout public class AwtBord extends Applet { Button botonN,botonS,botonE,botonO,botonC; public void init() { setLayout( new BorderLayout() ); // Craemos un boton en cada posicion que permite el layout botonN = new Button( "Norte" ); botonS = new Button( "Sur" ); botonE = new Button( "Este" ); botonO = new Button( "Oeste" ); botonC = new Button( "Centro" ); // Los hacemos aparecer en pantalla add( "North",botonN ); add( "South",botonS ); add( "East",botonE ); add( "West",botonO ); add( "Center",botonC ); } }
3.‐ GridLayout La composición GridLayout proporciona gran flexibilidad para situar Componentes. El layout se crea con un número de filas y columnas y los Componentes van dentro de las celdas de la tabla así definida. En la figura siguiente se muestra un panel que usa este tipo de composición para posicionar seis botones en su interior, con tres filas y dos columnas que crearán las seis celdas necesarias para albergar los botones:
Profesor: Quiñones Nieto, Yamil
Página 5
Lenguaje de Prgramacion II
4.‐ GridBagLayout Es igual que la composición de GridLayout, con la diferencia que los Componentes no necesitan tener el mismo tamaño. Es quizá el layout más sofisticado y versátil de los que actualmente soporta AWT. En la figura siguiente vemos la imagen generada por un panel que usa el GridBagLayout para soportar diez botones en su interior:
import java.awt.*; import java.applet.Applet; // Demostracion del uso del GridBagLayout // Vamos a crear nueve botones, fijando los Constraints para // que se pueda ver la flexibilidad que permite el uso de este // layout public class AwtGBag extends Applet { public void init() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints gbc = new GridBagConstraints(); setLayout( gridbag ); // Para este grupo fijamos la anchura y vamos variando alguna // de las caracteristicas en los siguientes, de tal forma que // los botones que aparecen en cada una de las lineas tengan // apariencia diferente en pantalla gbc.fill = GridBagConstraints.BOTH; gbc.weightx = 1.0; Button boton0 = new Button( "Botón 0" ); gridbag.setConstraints( boton0,gbc ); add( boton0 ); Button boton1 = new Button( "Botón 1" ); gridbag.setConstraints( boton1,gbc ); add( boton1 ); Button boton2 = new Button( "Botón 2" ); gridbag.setConstraints( boton2,gbc );
Profesor: Quiñones Nieto, Yamil
Página 6
Lenguaje de Prgramacion II
add( boton2 ); gbc.gridwidth = GridBagConstraints.REMAINDER; Button boton3 = new Button( "Botón 3" ); gridbag.setConstraints( boton3,gbc ); add( boton3 ); gbc.weightx = 0.0; Button boton4 = new Button( "Botón 4" ); gridbag.setConstraints( boton4,gbc ); add( boton4 ); gbc.gridwidth = GridBagConstraints.RELATIVE; Button boton5 = new Button( "Botón 5" ); gridbag.setConstraints( boton5,gbc ); add( boton5 ); gbc.gridwidth = GridBagConstraints.REMAINDER; Button boton6 = new Button( "Botón 6" ); gridbag.setConstraints( boton6,gbc ); add( boton6 ); gbc.gridwidth = 1; gbc.gridheight = 2; gbc.weighty = 1.0; Button boton7 = new Button( "Botón 7" ); gridbag.setConstraints( boton7,gbc ); add( boton7 ); gbc.weighty = 0.0; gbc.gridwidth = GridBagConstraints.REMAINDER; gbc.gridheight = 1; Button boton8 = new Button( "Botón 8" ); gridbag.setConstraints( boton8,gbc ); add( boton8 ); Button boton9 = new Button( "Botón 9" ); gridbag.setConstraints( boton9,gbc ); add( boton9 ); } } Para aprovechar de verdad todas las posibilidades que ofrece este layout, hay que pintar antes en papel como van a estar posicionados los Componentes; utilizar gridx, gridy, gridwidth y gridheight en vez de GridBagConstraints.RELATIVE, porque en el proceso de validación del layout pueden quedar todos los Componentes en posición indeseable. Además, se deberían crear métodos de conveniencia para hacer más fácil el posicionamiento de los Componentes. En el ejemplo siguiente, AwtGBagConv.java, creamos el método de conveniencia addComponente() para la incorporación de nuevos Componentes al layout, lo que hace más sencillo el manejo de los Constraints:
Profesor: Quiñones Nieto, Yamil
Página 7
Lenguaje de Prgramacion II
import java.awt.*; import java.applet.Applet; // Demostracion un poco mas avanzada del uso del GridBagLayout // para comprobar las facilidades public class AwtGBagConv extends Applet { GridBagLayout gridbag = new GridBagLayout(); // Creamos una funcion que permite incorporar automaticamente los // componentes, sin necesidad de tener que ir fijando los // constraints para cada uno de ellos void addComponente( Component comp,int gridx,int gridy, int gridw,int gridh ) { GridBagConstraints gbc = new GridBagConstraints(); gbc.gridx = gridx; gbc.gridy = gridy; gbc.gridwidth = gridw; gbc.gridheight = gridh; gridbag.setConstraints( comp,gbc ); add( comp ); }
public void init() { setLayout( gridbag ); // Incorporamos unos cuantos componentes de diversos tipos // utilizando nuestra funcion de a¤adir componente addComponente( new Label( "Nombre:" ),0,0,1,1 ); addComponente( new TextField( 12 ),1,0,2,1 ); addComponente( new TextArea( 5,20 ),0,1,2,2 ); addComponente( new Checkbox( "Sí?" ),2,1,1,1 ); addComponente( new List(),2,2,1,1 ); } }
5.‐ CardLayout Este es el tipo de composición que se utiliza cuando se necesita una zona de la ventana que permita colocar distintos Componentes en esa misma zona. Este layout suele ir asociado con botones de lista (Choice), de tal modo que cada selección determina el panel (grupo de componentes) que se presentarán. En la figura siguiente mostramos el efecto de la selección sobre la apariencia de la ventana que contiene el panel con la composición CardLayout:
Profesor: Quiñones Nieto, Yamil
Página 8
Lenguaje de Prgramacion II
import java.awt.*; import java.applet.Applet; // Demostracion del uso del CardLayout public class AwtCard extends Applet { Panel card; final static String PanelBoton = "Panel con Botones"; final static String PanelTexto = "Panel con Campo de Texto"; public void init() { // en la zona de seleccion del CardLayout, creamos un panel // con una lista de seleccion que nos permita seleccionar // entre dos paneles diferentes en la zona de visualizacion setLayout( new BorderLayout() ); Panel ac = new Panel(); Choice c = new Choice(); c.addItem( PanelBoton ); c.addItem( PanelTexto ); ac.add( c ); add( "North",ac ); card = new Panel(); card.setLayout( new CardLayout() ); // Uno de los paneles de la zona de visualizacion solo va a // contener botones Panel p1 = new Panel(); p1.add( new Button( "Botón 1" ) ); p1.add( new Button( "Botón 2" ) ); p1.add( new Button( "Botón 3" ) ); // El otro panel, contendra un campo de texto de 20 columnas Panel p2 = new Panel(); p2.add( new TextField( "Texto",20 ) ); // Incorporamos los paneles de visualizacion al Layout card.add( PanelBoton,p1 ); card.add( PanelTexto,p2 ); add( "Center",card );
Profesor: Quiñones Nieto, Yamil
Página 9
Lenguaje de Prgramacion II
}
// Solo manejamos el evento de la lista de seleccion, en funcion // de la opcion elegida presentara uno u otro de los paneles public boolean action( Event evt,Object arg ) { if( evt.target instanceof Choice ) { ( (CardLayout)card.getLayout() ).show( card,(String)arg ); return true; } return false; } }
6.‐CREAR UN LAYOUT Se puede crear un Layout personalizado en base a la interface LayoutManager. Hay que redefinir los cinco métodos que utiliza este interface, lo cual puede no resultar sencillo, así que en lo posible se deben utilizar los métodos de colocación de componentes que proporciona AWT, fundamentalmente en el momento en que parezca que ninguno de los Layouts que hemos visto satisface nuestras exigencias, deberíamos volver a comprobar que el GridBagLayout, que es el más flexible, de verdad no cumple nuestros requerimientos. No obstante, vamos a implementar un layout propio, MiLayout.java, para poder colocar los Componentes en posiciones absolutas del panel que contenga a este layout. Derivamos nuestro nuevo layout de LayoutManager y redefinimos los cinco métodos de la clase para que podamos posicionar los Componentes. import java.awt.*; // Implementación de un controlador de posicionamiento propio, que va // a permitir colocar los componenetes en cualquier lugar de su dominio // Tenemos que sobrecargar o definir los métodos que se utilizan en los // LayoutManager para que todo funcione, aunque no hagan nada, porque // aunque nosotros no llamemos explícitamente a esos métodos en ninguna // ocasión, es el propio sistema el que puede hacerlo public class MiLayout implements LayoutManager { // Constructor public MiLayout() { }
// Método para la incorporación de componentes public void addLayoutComponent( String name,Component comp ) { }
// Método para eliminar componentes del controlador public void removeLayoutComponent( Component comp ) { }
Profesor: Quiñones Nieto, Yamil
Página 10
Lenguaje de Prgramacion II
// Fija la dimensión del controaldor en función de la dimensión // de los componentes y su posición, para que se vean todos en // el espacio de pantalla destinado al controlador public Dimension preferredLayoutSize( Container parent ) { Insets insets = parent.insets(); int numero = parent.countComponents(); int ancho = 0; int alto = 0; for( int i=0; { Component Dimension Point p =
i < numero; i++ ) comp = parent.getComponent( i ); d = comp.preferredSize(); comp.location();
if( ( p.x + d.width ) > ancho ) ancho = p.x + d.width; if( ( p.y + d.height ) > alto ) alto = p.y + d.height; } return( new Dimension( insets.left + insets.right + ancho, insets.top + insets.bottom + alto ) ); }
// Controlamos la dimensión mínima que debe tener el controlador public Dimension minimumLayoutSize( Container parent ) { Insets insets = parent.insets(); int numero = parent.countComponents(); int ancho = 0; int alto = 0; for( int i=0; { Component Dimension Point p =
i < numero; i++ ) comp = parent.getComponent( i ); d = comp.preferredSize(); comp.location();
if( ( p.x + d.width ) > ancho ) ancho = p.x + d.width; if( ( p.y + d.height ) > alto ) alto = p.y + d.height; } return( new Dimension( insets.left + insets.right + ancho, insets.top + insets.bottom + alto ) ); }
// Reescala los componentes a su tamaño preferido en caso de que
Profesor: Quiñones Nieto, Yamil
Página 11
Lenguaje de Prgramacion II
// se pueda hacer public void layoutContainer( Container parent ) { int numero = parent.countComponents(); for( int i=0; i < numero; i++ ) { Component comp = parent.getComponent( i ); Dimension d = comp.preferredSize(); comp.resize( d.width,d.height ); } } } Y ahora vamos a ver un ejemplo en que utilicemos nuestro Layout. Posicionaremos tres botones en el panel y un campo de texto con una etiqueta precediéndolo. La apriencia que tendrá en pantalla será la que se muestra en la figura:
import java.awt.*; import java.applet.Applet; // Demostraci¢n de la creacion de un layout propio. Utilizamos el // layout que hemos definido en la clase MiLayout.class, que es un // layout que dispone de un metodo para posicionar los componentes en // coordenadas espec¡ficas de la pantalla public class AwtLibre extends Applet { Button boton1,boton2,boton3; Label etiqueta; TextField texto; public void init() { // Se utiliza nuestro dise¤o en el Applet setLayout( new MiLayout() ); // Colocamos tres botones, una etiqueta y un texto asociado boton1 = new Button( "Aceptar" ); boton2 = new Button( "Abrir" ); boton3 = new Button( "Cerrar" ); etiqueta = new Label( "Texto" ); texto = new TextField( "",20 );
Profesor: Quiñones Nieto, Yamil
Página 12
Lenguaje de Prgramacion II
// Incorporamos los componenetes al Layout add( boton1 ); add( boton2 ); add( boton3 ); add( etiqueta ); add( texto ); // Utilizamos el m‚todo "move" que hemos implementado para // nuestro layout, que nos permitira colocar los componentes en // posiciones especificas de la pantalla boton1.move( 0,10 ); boton2.move( 70,10 ); boton3.move( 30,40 ); etiqueta.move( 75,70 ); texto.move( 120,70 ); } }
Profesor: Quiñones Nieto, Yamil
Página 13