Ventanas,
marcos y cuadros de diálogo
La programación gráfica de aplicaciones Java que no son applets, requiere de una clase especial llamada Window y de dos extensiones suyas que se usan con mayor frecuencia que Window: Frame y Dialog, que en español se llaman marco y cuadro de diálogo respectivamente. Los objetos de la clase Window se llaman ventanas.
Pulsando el botón de este applet aparece un marco desde el cual se pueden lanzar: una ventana, un cuadro de diálogo y otro marco.
El alumno debe pulsar el botón "ventanas" y aparecerá un pequeño marco con tres botones: ventana, dialogo y marco, que al pulsarlos harán aparecer un objeto de cada clase.
Podrá observar que la ventana no tiene orilla ni título ni botón de salida, el cuadro de diálogo sí tiene orilla, título y botón de salida, pero no tiene botones de minimizar y maximizar ni un menú. Finalmente el marco tiene todo: orilla, título, botones de minimizar y maximizar y una barra de menú. Estas son precisamente las características que más distinguen entre sí a las ventanas, los cuadros de diálogo y los marcos.
El marco ofrece más funcionalidad que el cuadro de diálogo y éste más que una ventana. Por este motivo los marcos se utilizan con mayor frecuencia y las ventanas puras sólo de vez en cuando.
Abajo aparecen los contenidos de ventana.java, dialogo.java y marco.java que son las clases construídas para crear los objetos del ejemplo. El alumno debe estudiarlos cuidadosamente. El archivo ventanas,java responsable de crear el marco que lanza los otros tres, así como el applet que lanza las tres ventanas, se estudiarán como ejemplos de la Unidad 4. Por ahora el alumno debe prestar particular atención a la creación, configuración y despliegue de la ventana, el cuadro de diálogo y el marco del ejemplo.
El alumno observará los siguientes pasos en la construcción de todas las ventanas (y cuadros de diálogo y marcos):
(Se repite el applet junto a cada texto para que el alumno pueda mirar simultáneamente el código y las ventanas.)
El alumno observará que a pesar de que dialogo tiene botón para destruirlo, éste no funciona. Esto se debe a que lo único que ocurre cuando se pulsa ese botón es que se genera un evento de tipo WindowEvent pero nadie está haciendo nada con ese evento. Para que el botón funcione es necesario hacer que la ventana "escuche" estos eventos e implementar la interfaz WindowListener que tiene seis métodos abstractos. Esto puede verse en marco.java donde sí se programó que el marco se destruyera.
El alumno debe observar que cada marco que se crea aparece en la barra de tareas de Windows. Esto es porque los marcos son auténticas ventanas de Windows. En cambio las ventanas y los cuadros de diálogo son siempre dependientes de un marco y no dan lugar a un elemento de la barra de tareas. Esto se refleja en que los constructores de Window y Dialog requieren de un Frame que actúe como padre, mientras que el constructor de Frame no pide nada o tan sólo el título de la ventana.
En los ejemplos se mantuvo siempre el despliegue por defecto de la clase Window que es BorderLayout (recuerde que en cambio Panel tiene por defecto un despliegue de tipo FlowLayout) y sólo se agregaron tres botones a ventanas y una etiqueta a Ventana, a Dialogo y a Marco, pero no hay que olvidar que las ventanas son contenedores y por lo tanto se pueden utilizar en ellas todos los tipos de despliegues y agregarles todos los contenedores y componentes que se desee.
En Marco.java el alumno puede ver cómo se agrega una barra de menú a un marco y cómo se configura un menú. Éste es el tema de la última parte de esta unidad.
El applet ventanasApplet muestra cómo se crea y se abre un marco del tipo ventanas al pulsarse el botón de título "ventanas" que es el único componente de este applet.
El marco de tipo ventanas que se abre al pulsar el botón del applet ventanasApplet contiene tres botones cada uno de los cuales genera una ventana, un cuadro de diálogo o un marco de las clases expuestas arriba.
El alumno debe estudiar cuidadosamente el código del applet y del marco y entender cómo funcionan. Notará la implementación del método actionPerformed en ambos, que responde a las pulsaciones en los botones abriendo una ventana, un diálogo o un marco según corresponda. Los detalles de lo que significa actionPerformed y la interfaz ActionListener se explican en la unidad 4.
El applet ventanasApplet y las diversas ventanas que formas ente ejemplo constituyen una buena muestra de lo que se puede hacer con los diferentes tipos de ventanas del paquete java.awt.
Las barras de menús sólo pueden aparecer en un marco (Frame) y cada marco sólo puede tener una barra de menús. Para agregar una barra de menús a un marco basta crearla y asignarla al marco mediante la función setMenuBar. Es decir, basta escribir estas dos líneas:
MenuBar mb=new MenuBar();
setMenuBar(mb);
dentro de la construcción del marco. El método setMenuBar es un método de la clase Frame.
A una barra de menús se le pueden agregar menús. Para ello hay que construir cada menú dándole un nombre. Por ejemplo:
Menu archivo=new Menu("archivo");
Menu edición=new Menu("edición");
crea dos menús de nombre "archivo" y "edición" respectivamente. Estos dos menús pueden agregarse a la barra de menús mb de esta manera:
mb.add(archivo);
mb.add(edición);
Finalmente, a los menús se les pueden agregar elementos de menú (MenuItem) que se crean también asignándoles un nombre a cada uno. Por ejemplo:
MenuItem nuevo=new MenuItem("nuevo");
MenuItem abrir=new MenuItem("abrir");
MenuItem guardar=new MenuItem("guardar");
crea tres elementos de menú, los cuales pueden agregarse, por ejemplo, a archivo de esta manera:
archivo.add(nuevo);
archivo.add(abrir);
archivo.add(guardar);
Para crear una línea de separación dentro de un menú se agrega un elemento de menú de nombre "-" (signo menos) así;
archivo.add(new MenuItem("-"));
o simplemente:
archivo.add("-");
pues el método Menu.add(String cadena) crea un elemento de menú con nombre cadena y lo agrega al menú.
La instrucción
nuevo.setEnabled(false);
haría que la opción "nuevo" apareciera deshabilitada.
A un menú se le puede agregar otro menú así:
opciones=new Menu(opciones);
edición.add(opciones);
y también un CheckboxMenuItem que es una versión del interruptor (Checkbox) especial para incluirse en un menú.
Todas estas operaciones para construir un menú aparecen en el ejemplo siguiente. Al pulsar el botón "menú" aparece un marco con un menú completo para un programa. El alumno debe estudiar cuidadosamente el ejemplo y su código que aparece a continuación.
Para que un menú pueda usarse interactivamente en un programa es necesario implementar la interfaz ActionListener, lo cual consiste en implementar el método actionPerformed(ActionEvent). En este ejemplo se implementaron, de manera muy simple, las interfaces ActionListener y WindowListener para hacer que el marco se cierre tanto cuando se pulsa el botón de cerrar ventana que aparece arriba a la derecha en los marcos, como al elegir el MenuItem "cerrar" del menú. Para que las otras opciones del menú funcionaran sería necesario ampliar la implementación del método actionPerformed, así como registrar el marco como escucha (addActionListener) en todos los MenItems del menú. Todos estos temas relacionados con los eventos se estudian en la unidad 4.