La interfaz gráfica de Usuario (GUI por sus siglas en ingles) En Java es un capitulo extenso que iremos viendo a medida que avanzamos en los temas referente a este lenguaje. Puedes encontrar libros completos sobre las GUI's en java,
Generalmente a la programación de interfaz gráfica se le denomina swing, Swing es, hoy en dia, la API (si no sabes lo que es una API lee esto
http://en.wikipedia.org/wiki/Application_programming_interface) principal para programación a nivel gráfico y es parte de la JFC (Java Fundation Classes) Osea, se integra de manera nativa en Java. Swing es la evolución -por decirle así- de la antigua AWT (Abstract windows Toolkit) que también es un conjunto de clases diseñadas para implementar la interfaz gráfica en java.
El nacimiento de Swing de debe a las falencias obvias que se fueron dando en AWT en su implementación, algunas de ellas fueron:
- awt dependía de la plataforma en que se desarrollaba para mostrar sus componentes, es decir, se mostraba una barra distinta en windows y en unix lo que traía problemas con los esquemas y no funcionaba efectivamente para el objetivo primordial de java; la portabilidad extrema entre plataformas.
- Al depender íntimamente del sistema en que se ejecuta, awt añade funcionalidades básicas o mínimas para poder operar correctamente. aunque esto tiene un beneficio; los componentes de awt son mas livianos que los de Swing.
Por el contrario, Swing se implementa 100% a través del codigo volviéndose independiente de la plataforma en que se ejecuta. Swing a su vez es mucho mas personalizable de AWT al tratarse de clases insertadas en arboles amplios de herencia que pueden conbinarse sin romper los hilos del código. Swing permite emular estilos de ventanas como los de windows classic, windows en versiones posteriores, mac y linux entre otros, a través de su LOOK AND FEEL. una de las ventajas principales de swing es que permite a los programadores proveer su propia implementación de apariencia sin la necesidad de grandes cambios en el código, esto gracias a que swing apunta a la uniformidad visual de sus componentes.
JFrame
Comenzaremos nuestra discusión acerca de una de las cosas mas emocionantes de cualquier lenguaje (me refiero a la interfaz gráfica y diseño en general) con dibujos simples sobre un panel desplegado en pantalla, dejaremos de lado el terminal de netbeans para comenzar con las ventanas y gráficos.
Antes de comenzar a dibujar en un panel tenemos que comprender el sistema de coordenadas en Java.
De manera automática Java nos ubica el punto 0,0 en la parte superior izquierda de la pantalla o ventana dependiendo del objeto que trabajemos. Aclaro esto, cuando creamos un componente, por ejemplo un botón, y le damos la coordenada 100,250. no nos referimos a la coordenada 100,250 de nuestro monitor sino del componente donde vaya a encajar ese botón. vale aclarar esto.
La primera coordenada es el eje X y se refiere a la posición horizontal de la ventana o componente y la segunda coordenada se refiere al eje Y y se refiere a la posición vertical de la ventana o componente, en el que cada punto es en realidad un pixel.
Lo primero que debemos crear es una ventana o mejor dicho un marco que contenga los componentes que iremos añadiendo a ella, esto lo haremos atraves de la clase JFrame.
Como podemos ver en esta imagen JFrame es una version extendida de la clase Frame del paquete AWT, como muchos de los componente del paquete javax,swing JFrame añadió características avanzadas a los componentes básicos de Frame tal y como lo explique al principio de esta entrada.
Para crear un marco con JFrame vamos a crear una clase que extienda de esta.
linea 1 - importamos la clase JFrame del paquete javax.swing. lo que nos permitira ocupar a JFrame cuando queramos dentro de esta clase.
linea 3 - hacemos que nuestra clase extienda de JFrame (extends) con esto tenemos los constructors, métodos normales y variables de JFrame listas para ser sobrecargados o llamados. Es importante ya le dice al programa que nuestra clase es una subclase de JFrame con lo que podemos crear nuestros propios atributos para la ventana que construiremos.
linea 5 - Creamos un constructor de nuestra clase. de vital importancia ya que debemos hacer un llamado del constructor de JFrame.
linea 7 - atraves de super llamamos al constructor de JFrame con un argumento de tipo String, este argumento sera el titulo de la ventana. JFrame tambien tiene otras tres versiones de su constructor sobrecargadas. Lo mas comun es que llamemos a la que recibe un parametro String como en este caso o en su defecto podemos llamar simplemente a la version por defecto atraves de super(); sin mas.
Recuerda que podemos utilizar super para llamar al constructor de JFrame por que hemos especificado que nuestra clase extiende de esta ultima.
linea 8 - el metodo setSize de JFrame recibe dos argumentos (largo, alto) en este caso la ventana sera de 300 x 300. es uno de los métodos esenciales para la creación de ventanas o contenedores ya que determina el tamaño inicial del mismo. veremos que este tamaño puede ser o no modificable ya sea en expansión o contracción.
linea 9 - setVisible este metodo (de JFrame) establece si la ventana sera visible, para ello recibe un argumento de tipo booleano, true si queremos que se vea la ventana y false en caso contrario. este método no es implícito del frame por lo que en caso de no llamarlo por olvido o lo que sea, la ventana no se mostrara.
linea 10 - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); sirve para que al presionar sobre la X de la ventana osea cuando queremos cerrarla el proceso termine y no continúe ejecutándose en memoria. EXIT_ON_CLOSE es una variable de tipo int, declarada como final y static. osea el método setDefaultCloseOperation recibe un parámetro int para determinar si que debe hacer con la ventana.
lo mejor es siempre establecer este parámetro como en el ejemplo.
Con estos métodos dentro del constructor ya hemos creado la primera ventana!!!!
linea 15 - se crea un objeto de Ventana1 dentro del método main para que se ejecute el constructor. el resultado de la ejecución es la ventana que aparece a un constado del código. como podemos ver es un marco vacio con un encabezado y los respectivos botones de minimizar y maximizar. notese que la ventana tiene la misma apariencia de windows 7 que es el sistema donde se esta ejecutando.
Esta es otra manera de crear la ventana, hay libros donde lo hacen así, la única diferencia con el código anterior es que los métodos son llamados a través de la instancia de la clase directamente en el main. Ambos códigos son completamente validos y operativos.
tal vez hayas notado que la ventana aparece al costado superior izquierdo de la pantalla, pues bueno Java nos permite posicionar donde queramos la ventana para ello debemos hacer una llamada al metodo
setLocationRelativeTo();
JFrame hereda este método de la clase Window del paquete java.awt. y nos permite especificar en que lugar de la pantalla aparecerá nuestra aplicación a traves de un parametro de tipo component. por ahora solo utilizaremos como parámetro - null - lo que nos deja la ventana en el centro de la pantalla.
setLocationRelativeTo(null);
debemos localizar este metodo junto a los otros que pusimos en el constructor o donde este llamado el objeto JFrame.
JPanel
Ya creamos un marco de ventana para nuestra aplicacion de dibujo, ahora crearemos el "lienzo" en el que pondremos nuestros dibujos. para ello ocuparemos la clase JPanel.
JPanel es un contenedor simple que nos permite añadirle objetos como botones, barras, dibujar sobre el , etc...
Al igual que con JFrame debemos hacer que nuestra clase extienda de JPanel. Como sabemos una clase no puede extender de mas de una clase a la vez por lo que se suelen crear dos clases a la hora de crear una aplicación que dibuje. Aunque si se puede hacer en una sola clase. a ver si se te ocurre como!!!
JPanel y las clases que extiendan de ella cuentan con un método llamado paintComponent() que el sistema llama automáticamente cada vez que se utiliza un objeto JPanel. y es necesario que nosotros lo declaremos pues de lo contrario los objetos de JPanel podrían no mostrarse.
paintComponent requiere un argumento de tipo Graphics que sirve para crear dibujos y otras graficas.
La primera linea dentro del método paintComponent debe ser:
super.paintComponen(g);
esto asegura que el panel se muestre apropiadamente en la pantalla. por lo tanto quedaria asi.
paintComponent(Graphics g)
{
super.paintComponent(g);
......
......
}
ahora a partir del objeto Graphics g podemos llamar a los metodos apropiados para dibujar ovalos, cuadrados, letras etc...
lineas 1 y 2 - se hacen las importaciones de las clases que utilizaremos para dibujar. JPanel y Graphics.
linea 4 - hacemos que nuestra clase herede de JPanel (extienda).
linea 6 - hacemos una sobre escritura del método paintComponent pasandole un argumento Graphics para poder crear dibujos o lo que queramos (la g del parámetro es solo el nombre del argumento, se pone g para saber que es un objeto Graphics pero puede ser cualquiera).
linea 8 - se hace la llamada directa al método de la superclase, a traves de super. esto se hace para asegurar que se muestre correctamente en pantalla. yo he probado ejecutando los códigos sin esta llamada y no he tenido problemas al mostrar los componentes, pero aun así, es mejor asegurarse, ademas que esta llamada no genera desgaste de memoria.
Los metodos getWidth() y getHeight(); devuelven el ancho y la altura del panel en el momento respectivamente. en caso de que agrandemos o disminuyamos el tamaño de la ventana y por lo tanto del panel, se llama implícitamente a un método llamado repaint(); que vuelve a dibujar el objeto en el panel.
la linea 11 - llama al metodo drawLine(x, y, x ,y); Este método dibuja una linea recta y recibe 4 argumentos de coordenadas. los primeros dos especifican el primer punto y las otras dos el punto final, luego ambos puntos se unen formando la linea recta.
En este caso le pasamos (0 , 0 , ancho, alto); por lo que la linea inicial queda en la esquina superior izquierda
(0, 0) y el segundo punto queda en la esquina inferior derecha (ancho, alto).
Recordemos que las variables ancho y alto reciben el tamaño del panel en el momento. osea si el panel es de (300, 300) esas son las coordenadas de ancho y alto.
la linea 12 - pone drawLine(0 , alto, ancho , 0); con lo que ponemos el primer punto en la esquina inferior izquierda (0 , alto) recordar que alto tiene el valor del tamaño de alto del panel, por lo que queda de 0 horizontalmente y con alto para abajo.
acá el código de la clase ejecutora.
Este es el código de la clase que usamos para ejecutar el panel, si te fijas es practicamente la misma que utilizamos para crear el marco. es mas ¡¡¡es la misma!!! solo tiene algunas variaciones.
en la linea 10 - llamamos al método setLocationRelativeTo(null); que como la dije se utiliza para dejar la ventana en el medio de la pantalla.
linea 17 - se crea un objeto Panela que por consiguiente es un objeto JPanel.
linea 18 - se utiliza el método add de JFrame (recordar que Ventana1 por herencia es un objeto JFrame) y añadimos el panel para que se muestre en la ventana, sino se hace esto a través de "add" se mostrara solo el marco como en el primer ejemplo.
Ahora si agrandamos y disminuimos el tamaño de la ventana una vez ya ejecutada veremos como las lineas se vuelven a dibujar quedando siempre de esquina a esquina.