El gestor de diseño GridBagLayout

prev.gif (997 bytes)chapter.gif (1105 bytes)home.gif (1054 bytes)next.gif (998 bytes)

Gestores de diseño

Las propiedades que gobiernan este gestor de diseño

Ejemplo: diseño de una ficha


En esta página estudiamos un gestor de diseño bastante complicado, y que necesita de bastante práctica. Quizá la mejor descripción de este gestor se encuentre en el libro de David M. Geary. Graphic JAVA 1.1. Mastering the JFC (Volume I).  Prentice Hall (1998). En el libro viene incluída una aplicación denominada GridBagLab, con la que podemos experimentar los cambios en las propiedades de este gestor de diseño, y como afectan al aspecto de una matriz de botones. Varias imágenes tomadas de esta aplicación se han incluído en esta página.

 

Las propiedades que gobiernan este gestor de diseño

El gestor de diseño GridBagLayout es muy complicado, ya que está gobernado por un conjunto de propiedades que están interelacionados entre sí. Los componentes se disponen en una matriz tal como vimos al estudiar el gestor GridLayout. En la figura vemos la disposición de los controles y a la derecha los valores de los propiedades de dicho gestor para el primer control (en color gris oscuro)

gridBag1.gif (32019 bytes) gridBag1_1.gif (12170 bytes)

gridx y gridy señalan la posición del control en la matriz, el control seleccionado (titulado 1) esta en la fila cero y en la columna 0. Cada uno de los controles tiene una unidad de anchura y una unidad de altura tal como especifica las propiedades gridwidth y gridheight.

Vamos a cambiar la propiedad fill de su valor BOTH a NONE. Vemos que el control 1 está anclado (Anchor) en la parte superior izquierda (NORTHWEST) y tiene un tamaño menor que el área en el que se muestra. La clave de la comprensión del este difícil gestor está en esta figura, en la distinción entre el control (el 1 en gris oscuro) y el área en la que se puede mostrar.

gridBag2.gif (29356 bytes)

Cambiemos la propiedad Anchor de NORTHWEST (esquina superior izquierda) a CENTER (centro). El control 1 aparecerá de la forma en la que se indica en la figura.

gridBag3.gif (29806 bytes)

Cambiemos ahora la propiedad fill de NONE a HORIZONTAL. El control incrementa su tamaño horizontalmente hasta ocupar toda el área disponible.

gridBag4.gif (31837 bytes)

Partimos de la situación inicial restaurando el valor de la propiedad fill a BOTH (el control incrementa su tamaño hasta ocupar toda el área disponible tanto horizontalmente como verticalmente). Cambiemos la propiedad Insets de su valor por defecto (0, 0, 0, 0), estableciendo un margen de 10 unidades a la izquierda, a la derecha, arriba y abajo. El efecto se ve en la figura inferior.

gridBag5.gif (31118 bytes)

Restablezcamos todas las propiedades a su valor por defecto y examinemos el efecto del cambio en la propiedad gridwidth. Cambiemos ahora la propiedad gridwidth del control 2, de su valor por defecto 1, a la constante REMAINDER. Vermos en la figura que este control se convierte en el último de la primera fila. El control ocupa toda el área disponible por que su propiedad fill tiene el valor de BOTH.

Como veremos en el ejemplo, REMAINDER es el valor de la propiedad gridwidth del último elemento de una fila.

gridBag6.gif (32176 bytes)

Una vez que hemos visto las propiedades fundamentales del gestor GridBagLayout, vamos a usarlas para diseñar una ficha.

 

Ejemplo: diseño de una ficha

disco.gif (1035 bytes)gridBag1: GridbagApplet.java

Vamos a estudiar los pasos necesarios para crear una ficha como la que muestra la figura empleando el gestor de diseño GridBagLayout

gridBag8.gif (4820 bytes)

Se crea un applet con el asistente de creación de applets.

Vamos ahora al modo diseño, pulsando con el ratón en la pestaña Design. Nos aseguramos de que this (el applet) tiene establecido el gestor de diseño XYLayout. En el caso de que no lo tenga establecido, seleccionar this en el panel de estructura y cambiar su propiedad layout a XYLayout en su editor asociado.

Añadimos un panel en la parte inferior del applet y varios controles en la parte superior. Sobre el panel situamos dos botones.

gridBag7.gif (3465 bytes)

El panel

Poner un panel en la parte inferior y cambiar su propiedad name

   Panel panelBotones = new Panel();

Seleccionar en el panel de estructura  panelBotones y cambiar su propiedad layout a XYLayout

Poner dos botones sobre el panel. Cambiar sus propiedades name y   label

   Button btnPago=new Button();
   Button btnCancelar=new Button();
   btnPago.setLabel("Comprar");
   btnCancelar.setLabel("Cancelar");

Seleccionar de nuevo en el panel de estructura panelBotones y cambiar su propiedad layout a FlowLayout. Los botones se sitúan en el centro del panel. Opcionalmente, establecer un espaciado horizontal entre los botones.

 

El applet

Situar los siguientes controles sobre el applet cambiando su propiedad name.

    Label titulo=new Label();
    Label nombre=new Label();
    Label direccion=new Label();
    Label pago=new Label();
    Label telefono=new Label();
    Label ciudad=new Label();
    Label provincia=new Label();

    TextField textNombre=new TextField();
    TextField textDireccion=new TextField();
    TextField textCiudad=new TextField();
    TextField textProvincia=new TextField();

    Choice chPago=new Choice();

Cambiar las propiedades de los controles a los valores que se indican en el código de la función miembro init.

        titulo.setText("Compre algo ahora");
        titulo.setFont(new Font("Times-Roman", Font.BOLD + Font.ITALIC, 16));
        nombre.setText("Nombre:");
        direccion.setText("Dirección:");
        pago.setText("Método de pago:");
        telefono.setText("Teléfono:");
        ciudad.setText("Ciudad:");
        provincia.setText("Provincia:");

        textNombre.setColumns(25);
        textDireccion.setColumns(25);
        textCiudad.setColumns(15);
        textProvincia.setColumns(2);

        btnPago.setLabel("Comprar");
        btnCancelar.setLabel("Cancelar");

Volver al modo código fuente (pulsar sobre la pestaña Source). Añadir elementos al control selección (Choice) denominado chPago.

       chPago.add("Visa");
       chPago.add("MasterCard");
       chPago.add("Caja Ahorros");

 

El gestor de diseño GridBagLayout

Eliminar en el código fuente todas las líneas de código que hacen referencia al gestor XYLayout.

Crear dos objetos uno de la clase GridBagLayout y otro de la clase GridBagConstraints. El segundo objeto establece los constraints. El objeto gbc tiene los valores por defecto que hemos mencionado en el primer apartado. Si se cambia un valor de una propiedad (gridwidth, anchor, fill, etc) el cambio permanece hasta que se vuelve a establecer otro valor.

    GridBagLayout gbl=new GridBagLayout();
    GridBagConstraints gbc=new GridBagConstraints();

Establecer el gestor de diseño GridBagLayout mediante setLayout.

       setLayout(gbl);

Añadir los componentes al applet

Se añade un componente al applet (o a un panel) en el que se ha establecido el gestor de diseño GridBagLayout, y se han definido los constraints del siguiente modo.

   add(componente, constraints);

La primera fila está formada por un único (REMAINDER) componente el titulo, centrado en la parte superior (NORTH)

        gbc.anchor=GridBagConstraints.NORTH;
        gbc.gridwidth=GridBagConstraints.REMAINDER;
        add(titulo, gbc);

La segunda fila, está formada por dos controles, nombre y a continuación textNombre. El primero está anclado (anchor) al este (WEST), antes estaba en NORTH, gridwidth toma el valor 1 (por defecto) antes estaba en REMAINDER. Como textNombre es el último control de la fila gridwidth vuelve a tomar el valor REMAINDER. Los controles ocupan todo el espacio horizontal disponible, la propiedad fill toma el valor HORIZONTAL

        gbc.fill=GridBagConstraints.HORIZONTAL;
        gbc.anchor=GridBagConstraints.WEST;
        gbc.gridwidth=1;
        add(nombre, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textNombre, gbc);

La tercera fila, está formada por dos controles: direccion y textDireccion. Las propiedades anchor y fill ya tienen fijados sus valores a WEST y HORIZONTAL, por lo que no hay que volver a establecerlo. Como textDireccion es el último control de la fila su propiedad gridwidth toma el valor REMAINDER.

        gbc.gridwidth = 1;
        add(direccion, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textDireccion, gbc);

La cuarta fila, está formada por cuatro controles: ciudad, textCiudad, provincia y textProvincia. Cuando se coloca el último control textProvincia, su propiedad gridwidth toma el valor REMAINDER.

	gbc.gridwidth = 1;
        add(ciudad, gbc);
        add(textCiudad, gbc);
        add(provincia, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textProvincia, gbc);

La quinat fila, está formada por dos controles: pago y chPago. El código es semejante, salvo la propiedad fill que toma el valor NONE antes estaba en HORIZONTAL. Esto hace que el control chPago no ocupe toda el área disponible, extendiéndose horizontalmente hasta alinearse con los otros controles por la parte derecha.

	gbc.gridwidth = 1;
        add(pago, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.fill=GridBagConstraints.NONE;
        add(chPago, gbc);

Finalmente, añadimos el panel panelBotones centrado. Cambiamos la propiedad anchor de WEST a SOUTH.

        gbc.anchor=GridBagConstraints.SOUTH;
        add(panelBotones, gbc);

Terminamos el diseño de la ficha separando convenientemente las filas de controles con objetos de la clase Insets, tal como se muestra en el código.

public class GridBagApplet1 extends Applet {
    Panel panelBotones = new Panel();

    Label titulo=new Label();
    Label nombre=new Label();
    Label direccion=new Label();
    Label pago=new Label();
    Label telefono=new Label();
    Label ciudad=new Label();
    Label provincia=new Label();

    TextField textNombre=new TextField();
    TextField textDireccion=new TextField();
    TextField textCiudad=new TextField();
    TextField textProvincia=new TextField();

    Choice chPago=new Choice();

    Button btnPago=new Button();
    Button btnCancelar=new Button();

    GridBagLayout gbl=new GridBagLayout();
    GridBagConstraints gbc=new GridBagConstraints();
    FlowLayout flowLayout1=new FlowLayout();

    public void init() {
        setBackground(Color.lightGray);
//propiedades de los controles
       	titulo.setText("Compre algo ahora");
        titulo.setFont(new Font("Times-Roman", Font.BOLD + Font.ITALIC, 16));
        nombre.setText("Nombre:");
        direccion.setText("Dirección:");
        pago.setText("Método de pago:");
        telefono.setText("Teléfono:");
        ciudad.setText("Ciudad:");
        provincia.setText("Provincia:");

        textNombre.setColumns(25);
        textDireccion.setColumns(25);
        textCiudad.setColumns(15);
        textProvincia.setColumns(2);

        btnPago.setLabel("Comprar");
        btnCancelar.setLabel("Cancelar");

        chPago.add("Visa");
        chPago.add("MasterCard");
        chPago.add("Caja Ahorros");

//gestor gridBaglayout
        setLayout(gbl);

//primera fila - título
        gbc.anchor=GridBagConstraints.NORTH;
        gbc.insets=new Insets(0,0,10,0);
        gbc.gridwidth=GridBagConstraints.REMAINDER;
        add(titulo, gbc);
//segunda fila - nombre
        gbc.fill=GridBagConstraints.HORIZONTAL;
        gbc.anchor=GridBagConstraints.WEST;
        gbc.gridwidth=1;
        gbc.insets=new Insets(0,0,0,0);
        add(nombre, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textNombre, gbc);
//tercera fila - dirección
        gbc.gridwidth = 1;
        add(direccion, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textDireccion, gbc);
//cuarta fila - ciudad   - provincia
        gbc.gridwidth = 1;
        add(ciudad, gbc);
        add(textCiudad, gbc);
        add(provincia, gbc);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        add(textProvincia, gbc);
//quinta fila - pago
        gbc.gridwidth = 1;
        add(pago, gbc);
        gbc.insets=new Insets(5,0,5,0);
        gbc.gridwidth = GridBagConstraints.REMAINDER;
        gbc.fill=GridBagConstraints.NONE;
        add(chPago, gbc);
//panel de los botones
	panelBotones.setLayout(flowLayout1);
        panelBotones.add(btnPago);
        panelBotones.add(btnCancelar);

        gbc.anchor=GridBagConstraints.SOUTH;
        gbc.insets=new Insets(15,0,0,0);
        add(panelBotones, gbc);
    }
}