Inicialmente Java tenía una kit de herramientas para crear interfaces gráficas denominada «Abstract Window Toolkit» (AWT). Simplificando, el funcionamiento de la misma consiste en llamadas a subrutinas del sistema operativo. Por ejemplo, al crear un botón o un cuadro de comprobación se llama a la subrutina correspondiente del S.O. Pero esto puede ser una ventaja o desventaja según se mire, ya que un cuadro de comprobación es distinto en cada sistema operativo. En el fondo, cada elemento tienes sus peculiaridades en cada sistema operativo y, por tanto, AWT sólo contiene los aspectos comunes que pueden ser invocados en cualquier sistema. Otra desventaja no menos importante es que hay desarrolladores a los que les gusta que sus «creaciones» se «vean» igual en cualquier plataforma, esto con AWT no es posible :).
En estas apareció Swing para solucionar estos «problemas». ¿La clave? Utiliza Java 2D para invocar subrutinas de bajo nivel en vez de utilizar el módulo de interfaz de usuario de alto nivel del S.O. Es decir, el elemento es el mismo en cualquier plataforma.
Entrar en todos los detalles de una interfaz gráfica nos daría para escribir un libro. Es por eso que sólo quiero hacer una pequeña introducción a los aspectos básicos de la misma.
Tres elementos son los que podemos considerar como fundamentales:
- Componentes: elementos gráficos tales como botones, cuadros desplegables, cuadros de texto, etc.
- Contenedores: elementos que contienen otros componentes o contenedores, por ejemplo JPanel o JFrame.
- Layouts: diseño aplicable a los contenedores, es la forma de distribuir los componentes dentro del contenedor.
La diferencia entre contenedores y componentes es clara, unos contienen a otros. Pero… ¿que es eso del layout? Como su propio nombre indica es un diseño que se aplica a los contenedores. Es decir, nos echa una mano a la hora de colocar los componentes en los contenedores. Por ejemplo, si tenemos el diseño BorderLayout el contenedor se divide en cinco zonas (como se puede ver en la siguiente imagen):
De esta forma podemos indicar fácilmente que un botón u otro contenedor se incluya en la parte sur del contenedor principal. Existen varios tipos de layouts, y también existe la posibilidad de establecer a null el layout de un contenedor e indicar la posición donde colocar el componente.
Una implementación básica de una ventana podría ser un JFrame, que tiene un JPanel con un BorderLayout y este un JButton en el sur.
//Creamos el marco JFrame jFrame = new JFrame(); //Creamos el panel principal JPanel jPanel = new JPanel(); //Establecemos el layout del panel jPanel.setLayout(new BorderLayout()); //Creamos un botón y lo añadimos al panel en el sur JButton jButton = new JButton("Aceptar"); jPanel.add(jButton,BorderLayout.SOUTH); //Establecemos el panel principal del marco jFrame.setContentPane(jPanel); //Cambiamos el tamaño y lo hacemos visible jFrame.setSize(200, 200); jFrame.setVisible(true);
Si se ejecuta el código anterior se obtiene el siguiente resultado:
Podemos encontrar una similitud entre los elementos que componen la ventana y un cuadro. El JFrame sería el marco, el JPanel sería el lienzo y el layout, con el resto de componentes, sería el dibujo en sí.