Componentes, Contenedores y Cursores


 


Las unidades 1,2,3, 4 y 5 estudian la creación de interfaces gráficas de usuario. Dichas unidades se basan en los  paquetes java.awt y java.awt.event, por lo que conviene que el alumno los localice en la documentación oficial del API de Java y consulte esa parte de la documanteción frecuentemente. Como podrá observar, se trata de dos paquetes muy grandes con muchas clases e interfaces y es imposible cubrirlos totalmente en un curso de programación. Sólo se cubrirán los aspectos más importantes. El alumno deberá consultar frecuentemente la documentación para hacer los ejercicios.

 

Interfaces gráficas de usuario

Una interfaz gráfica de usuario consta de varios componentes como botones, menús, listas, barras de desplazamiento, etc. con los que el usuario de un programa puede interactuar para intercambiar información con programa. Los componentes gráficos sirven para mostrar información al usuario y para que el usuario elija o escriba nueva información que el programa podrá usar en su funcionamiento. Una interfaz gráfica tiene componentes acomodados en uno o varios contenedores pero además tiene también un sistema para recibir información del usuario, ese sistema son los eventos. En la unidad 1 de este curso se estudian los componentes, los contenedores y los cursores que ell ratón puede tener en cada componente. En la unidad 2 se estudian las diversas maneras en que se pueden acomodar los componentes gráficos en un contenedor. La unidad 3 estudia los distintos tipos de ventanas en las que se pueden poner los contenedores y componentes de un programa y los menús que pueden tener dichas ventanas. Para completar el estudio de las interfaces gráficas de usuario, la unidad 4 presenta los eventos con los que se puede programar la interacción del usuario con los componentes gráficos. Finalmente la unidad 5 enseña cómo se pueden hacer dibujos en los componentes gráficos y cómo utilizar colores y distintos tipos de letras para enriquecer visualmente una interfaz gráfica.

Para que una interfaz gráfica funcione es necesario utilizar los eventos. Los eventos se estudian detenidamente en la unidad 4 pero se utilizan ocasionalmente en las unidades anteriores cuando es necesario dar alguna funcionalidad a los ejemplos. Este uso "extemporáneo" de los eventos no debe distraer al alumno del tema de la unidad, pero servirá para que se vaya familiarizando poco a poco con los eventos que son, a fin de cuentas, el alma de los programas interactivos.

 

Componentes

En esta sección se estudian los componentes gráficos de Java que son los elementos básicos con los que se construye la interfaz gráfica de un programa. Los componentes gráficos son subclases de la clase java.awt.Component. Un componente es un objeto que tiene una representación gráfica que consta de un rectángulo con algún dibujo dentro. Para saber el tamaño de un componente se puede usar el método getSize() que devuelve un objeto de clase Dimension. El ancho de un componente C se obtiene con C.getSize().width, y su altura con C.getSize().height. Para dar un tamaño específico a un componente C se puede utilizar el método setSize(int width,int height). Es importante saber que la mayoría de los componentes que vamos a estudiar tienen un tamaño por defecto, muchas veces dependiente de su contenido y que aunque es posible darles el tamaño que se desee, también es posible respetar su tamaño por defecto.

Es importante aclarar algo sobre el tamaño y la colocación de los componentes en un contenedor. El paquete awt fue diseñado para que sus componentes sean utilizados en combinación con despliegues (Layouts). La idea es que los componentes adquieran el tamaño que conviene según la manera en que el programador desea acomodarlos. Por este motivo no siempre es conveniente ni fácil fijar el tamaño de un componente. En la sección sobre despliegues se aclarará este tema.

Para estudiar los principales componentes comenzaremos colocándolos en un applet y lo haremos respetando su tamaño por defecto cuando lo tienen. Para ello se colocarán en un applet que tiene por defecto un despliegue  que acomoda los componentes de manera natural respetando su tamaño. Los diversos sistemas de despliegue se estudian en la unidad 2. Más adelante, en la unidad 3, veremos cómo se pueden colocar los componentes en una ventana, en un marco o en un cuadro de diálogo.

A continuación se presenta un ejemplo de cada uno de los componentes más usados, cada uno en un applet, con los nombres en castellano que usaremos durante el curso y el código que generó el ejemplo a la derecha. El alumno debe estudiar cada ejemplo para aprender la manera de crear e inicializar los componentes.

Button

botón

Canvas

pizarra

Checkbox

interruptor

CheckboxGroup

grupo

Choice

selector

Label

etiqueta

List

lista

Scrollbar

barra de
desplazamiento

TextArea

cuadro de texto

TextField

campo de texto

Como puede verse en los ejemplos de la tabla, para colocar un componente en un contenedor (en este caso en un applet), se siguen cuatro pasos: primero hay que definir una variable del tipo deseado, después hay que crear una instancia del componente, luego hay que configurarlo y finalmente, agregarlo al contendor (o como veremos más adelante a un contenedor). 

Los cuatro pasos utilizados en la construcción de un componente:definir variable, construir el objeto, configurarlo y agregarlo a un contenedor, pueden mezclarse y a veces en una sola instrucción se pueden dar dos o tres pasos. Por ejemplo:

realiza en dos líneas los cuatro pasos. En la primera línea se declara la variable, se crea una instancia y se configura parcialmente asignándole su contenido. En la segunda línea sólo se agrega el campo de texto al contenedor. Lo mismo puede hacerse así:

Observa que en el caso del botón no se creó ninguna variable, sino que se agregó directamente al applet el botón creado. Esto se hizo así sólopara ilustrar que es posible, pero en general conviene más declarar siempre una variable del tipo del componente que se va a agregar, crear el componente usando uno de sus constructores y luego configurar el componente agregándole cosas o definiendo sus propiedades.

Observa que a la pizarra (Canvas) fué necesario darle un tamaño porque no tiene tamaño por defecto, mientras que a todos los demás no fue necesario definirles el tamaño. A la pizarra también se le definió un color de fondo (background), cosa que podría hacerse con cualquiera de los componetes. En general, si a un componente no se le define un color de fondo, es de color gris claro o bien hereda el color del contenedor en el que se ha colocado, en este caso, el del applet. 

Observa cómo se crean los interruptores y los grupos que constan de un conjunto de interruptores de los cuales sólo uno puede estar activado. La representación gráfica de los interruptores libres es un cuadrado con una etiqueta a su derecha, mientras que los de un grupo se representan como círculos también con una etiqueta a la derecha. Lo que determina que un interruptor es libre o pertenece a un grupo es si se construyó utilizando un constructor que no lleva grupo (CheckboxGroup) o usando uno que sí lo especifica.

El alumno debe observar que grupo, es decir CheckboxGroup, no es un componente sino que se construye como un conjunto de interruptores. Sólo uno de los interruptores de un grupo puede tener valor true. Hay una diferencia en la presentación gráfica de un interruptor que pertenece a un grupo (círculos) respecto a los independientes (cuadros).

En el caso de la etiqueta se cambió no sólo su color de fondo (background) sino también el del texto o color "de frente" (foreground).

Observa que para agregar elementos a un selector (Choice) o a una lista se hace después de construir el objeto utilizando el método addItem(String) en el primer caso y el método add(String) en el segundo.

Las barras de desplazamiento al construirlas hay que especificar si son horizontales o verticales. Observe que en este caso se utilizó un despliegue diferente del que tiene por defecto el applet con el objeto de colocar las barras donde suelen aparecer por ejemplo en un editor de textos. En la unidad 2 se estudia este tipo de despliegue.

Al definir un cuadro de texto se puede determinar su tamaño en "columnas" y "filas". En realidad el tamaño que adquiere el cuadro de texto corresponde aproximadamente al número de filas y columnas que le caben usando la fuente de letras Courier o Monospaced de tamaño 12. Las fuentes de letras se estudian en la unidad 4.

He aquí una construcción muy frecuente:

En este caso no se declara la variable, sólo se crea la etiqueta y se agrega en la misma línea al contenedor. Esto puede hacerse cuando no deseamos en el futuro modificar o utilizar la etiqueta y por tanto no hace falta conservar una referencia a ella.

El siguiente ejemplo muestra varios componentes. El alumno debe estudiar el código que los ha generado observando los diferentes constructores y los métodos que se han usado para lograr las diferentes configuraciones. Los métodos empleados para cambiar colores y tipos de letras se estudiarán detenidamente en la unidad 4, sin embargo el alumno deberá usarlos igual que se usan en este ejemplo en los ejercicios de esta unidad.

Las listas muestran cierto número de filas (por defecto 4). Si la lista tiene más elementos que filas, aparece una barra de desplazamiento que permite ver todo el contenido de la lista. Lo mismo ocurre cuando el contenido de un cuadro de texto no cabe en el rectángulo asignado al cuadro.

Component es una clase abstracta que tiene muchos métodos, pero no es necesario conocerlos todos para usar sus clases derivadas. Lo importante es conocer sus métodos más usados y éstos se pueden ver en los ejemplos anteriores y en los que se presentarán en esta misma lección. Para crear los componentes de una interfaz gráfica, en la práctica, es imprescindible tener a mano la documentación del API de Java y consultarlo continuamente.

En los ejemplos de las siguientes secciones de esta lección, se verán más casos de construcciones y configuraciones de componentes. La manera de aprender a usar y configurar componentes es mirando muchos ejemplos y haciendo otros con ayuda de la documentación del paquete java.awt.




Contenedores

Un contenedor es una clase derivada de la clase Container. Los contenedores son componentes que tienen la capacidad de albergar otros componentes. En particular Applet es un contenedor.

Los contenedores más usados son Panel y Window. De hecho los otros contenedores que se usan son extensiones de éstos. Applet es extensión de Panel. Frame y Dialog son extensiones de Window. Por tanto es importante estudiar antes Panel y Window.

Panel es el contenedor más usado. Se utiliza únicamente como apoyo para acomodar componentes. Su aplicación está muy relacionada con el uso de los Despliegues (Layouts) que se estudian en la siguiente sección. Normalmente para crear una interfaz de usuario se utilizan varios paneles cuya única misión es contener componentes u otros paneles que a su vez contienen componentes y paneles.

Un Panel no puede desplegarse solo, tiene que estar contenido en un applet o en una ventana (Window). Las ventanas son los contenedores de la clase Window y estos sí pueden desplegarse solos, aunque en la mayoría de las aplicaciones se utilizan para esto las clases Frame (Marco) y Dialog (Cuadro de diálogo), ambas subclases de Window.

El alumno puede ver ejemplos de paneles (los applets son paneles) y de marcos (que son ventanas) en la unidad 8 del curso de Java Inicial. Las aplicaciones más interesantes de los contenedores dependen de los despliegues, por lo cual se estudiarán ambas cosas simultáneamente en los ejemplos de la siguiente lección.

La siguiente sección explica cómo se utilizan los cursores del ratón.




Cursores

En la primera versión de Java (el JDK 1.0) sólo se podía cambiar el cursor en las ventanas (subclases de Window), pero a partir del JDK 1.1  es posible asignar cualquiera de los 13 cursores predeterminados a cada Component. A partir de Java 2 es posible crear cursores nuevos a partir de imágenes. En esta sección sólo explicaremos cómo utilizar los cursores predeterminados, lo cual es muy sencillo. Para muestra basta un botón... bueno, en este caso hemos hecho un applet con 13 botones. Los botones tienen los nombres de los cursores que se les han asignado. Basta que el lector pase el cursor del ratón sobre el botón para que éste cambie al asignado a ese botón.

Aquí vería un applet si su navegador reconociese la etiqueta de APPLET.

Abajo aparece el código Java de este applet. Como el lector podrá comprobar, para asignar un cursor a un componete bastan dos pasos:

1) Crear un cursor del tipo deseado con la instrucción Cursor cur= new Cursor(int cursorIndex);
utilizando uno de los valores predeterminados Cursor.HAND_CURSOR, Cursor.DEFAULT_CURSOR, etc...

2) Asignar el nuevo cursor al Component comp mediante la instrucción comp.setCursor(cur);

Aquí vería un applet si su navegador reconociese la etiqueta de APPLET.

El método getCursor() de Component devuelve el número del cursor asignado a la componente. Por defecto todos los componentes tienen asignado el DEFAULT_CURSOR.

Nota: Si se desea cambiar sólo temporalmente el cursor asignado a un componente, a un applet o a una ventana, para recuperar el cursor por defecto conviene utilizar comp.setCursor(null), en general no es buena idea tratar de guardar el cursor anterior y volver a ponerlo.

Ejercicios