Tabla de Contenidos

GUIs en Java

Pequeña introducción

AWT

Para crear una ventana debemos implementar una clase que herede de java.awt.Frame. Los métodos que pueden sernos útiles en un frame son:

Applets

<APPLET code = "Aplt.class" width = "500" height = "300"></APPLET>

Eventos

Cómo funcionan?

Hemos de tener en cuenta que todo lo que veremos aquí, aunque sean para un javax.swing.JFrame, son objetos del paquete java.awt.events.
Los eventos en Java funcionan con “escuchadores” y “adaptadores”, necesitamos añadir un escuchador para poder controlar el evento (un adaptador es un objeto escuchador más sofisticado), es decir, un control tiene métodos para añadir escuchadores: addComponentListener, addKeyListener, addFocusListener… Todos ellos reciben el objeto que implementa la interfaz correspondiente (nosotros podríamos crear objetos que la implementasen, pero recuerda, deberíamos sobreescribir sus métodos, aunque fuesen innecesarios) o pasarle un objeto nativo de java que ya tenga implementada la interfaz (adaptador), la interface corresponde al Listener, y luego sobreescribir el método que nos interese.
Tal vez te preguntes si es necesario crear la nueva clase, hacer que herede, pero, y luego? como llamamos a los métodos de nuestra clase? Gracias a una proiedad de java cuyo nombre no quiero acordarme (creo que son métodos anónimos, pero no me hagas mucho caso), puedes hacerlo in situ:
P.ej. (código en un método de un JFrame):

		...
		this.addKeyListener(new KeyAdapter() {
			public void keyPressed(KeyEvent e)
			{
				TeclaApretada(e);
			}
		});
		...

Hemos llamado al método addKeyListener y pasado un KeyAdapter (este hereda de la interface KeyListener) que hemos creado en la llamada y a la vez le hemos dado ahí el cuerpo. su cuerpo ha sido una sobreescritura del método keyPressed (cuando se ha pulsado la tecla) que llama a otro método de JFrame, TeclaApretada:

		...
		private void TeclaApretada (KeyEvent e)
		{
			this.setTitle(e.toString());
		}

No olvides usar la ayuda para ver las clases que heredan de los escuchadores (adaptadores), o también para comprobar qué métodos puedes sobreescribir.

Eventos de teclado

Podemos usar el evento 'keyPressed' del Frame para detectar qué tecla ha sido pulsada. El método correspondiente a este evento nos trae un objeto java.awt.event.KeyEvent, ese objeto tiene un método llamado getKeyCode() que devuelve un int, ese int podemos compararlo con constantes existentes dentro de la misma clase KeyEvent.
Como bien sabemos, podemos usar estas constantes en un switch:

switch(evt.getKeyCode())
{
	KeyEvent.VK_SPACE:
...

Para controlar el KeyDown usaremos el método KeyPressed y el KeyUp con el KeyReleassed.

Eventos de Mouse

Eventos de formulario (resize)

Para capturar el evento que indica que una venta cambia de tamaño necesitamos un component listener….

        addComponentListener(new java.awt.event.ComponentAdapter() {
            public void componentResized(java.awt.event.ComponentEvent evt) {
                ...
          }
        });

Crear un evento personalizado

Para crear nuestros eventos tendremos que lidiar con la clase java.util.EventObject y con la interface java.util.EventListener. Cada clase que represente un evento heredará de EventObject, para que podamos capturar concretamente este evento tendremos que programar otra interface listener que herede de EventListener, ésta será implementada por la clase que tenga que capturarlo. Por lo tanto en este juego tenemos unos cuantos jugadores:

  1. Interface que extiende EventListener.
  2. Clase que implementa a la interface anterior (1).
  3. Clase que representa el evento, hereda de EventObject.
  4. Clase que lanza el evento.

Veamos una posible codificación para un evento, la clase EventObject obliga a que al constructor se le pase un objeto (este ha de ser el que crea el evento):

public class evento extends java.util.EventObject {
    private String str;
    public evento (Object obj, String msg) {
        super(obj);
        this.str = msg;
    }
    public String getStr () {
        return this.str;
    }
}

Un ejemplo de la interface:

public interface myIntListener extends EventListener {
    public void Captura (evento evt);
}

Y de la clase que implementa la interface, esta cuando se lanza el envento escribirá por pantalla el string que viene dentro:

public class myListener implements myIntListener {
    public void Captura(evento evt) {
        System.out.println(evt.getStr());
    }
}

Y aquí la clase que lanza el evento, list es un objeto asignado de la clase myListener o de la interface myIntListener, esto no importa:

this.list.Captura(new evento(this, "afds"));

Ejemplo

Otro ejemplo sería utilizando esta misma interface myIntListener, este mismo EventObject evento y dos formularios, uno con un botón que al pulsarse lanzará el evento al segundo formulario que cambiará su título con el texto que le venga en el objeto evento. Para que esto pueda salir bien el segundo formulario debe implementar myIntListener. En el primer formulario habría este código:

myIntListener esc;
public void setListener (myIntListener mil) {
   this.esc = mil;
}

Una vez llamado a este método setListener pasándole por parámetro el segundo formulario se lanzaría con la siguiente línea:

this.esc.Captura(new evento(this, "título"));

El segundo formulario sería algo parecido a esto:

public class NewJFrame1 extends javax.swing.JFrame implements myIntListener {
    public void Captura(evento evt) {
        this.setTitle(evt.getStr());
    }
}

Aunque el lanzador del evento perfectamente podría tener un array con más listeners. No?

Controles

Listas

El control Lista en Java es el javax.Swing.JList, este puede ser de tres tipos según su forma de seleccionar los elementos internos:

  1. SINGLE_SELECTION, cuando sólo puedes seleccionar un elemento.
  2. SINGLE_SELECTION_INTERVAL, cuando puedes seleccionar varios contiguos.
  3. MULTIPLE_SELECTION_INTERVAL, cuando puedes seleccionar varios elementos.

Estas son constantes estáticas dentro de la clase javax.swing.ListSelectionModel con valores enteros los cuales has de pasar al método setSelectionMode de la lista.

Cómo manejar los elementos una lista

Para rellenar una lista se utilizan los ListModel, estos son unos objetos que rellenas de elementos y que luego se pasan a la lista mediante el método de esta setListModel. Estos objetos permiten añadir elementos mediante métodos como add o addElement, eliminarlos con los remove, etc.
Para recoger el ListModel de una lista utilizarás el método getListModel de esta.

Cómo...

Mensajes

La clase para crear mensajes es la javax.swing.JOptionPane, esta tiene un montón de métodos estáticos que te muestran los famosos cuadros de mensajes:

javax.swing.JOptionPane.showMessageDialog(this, e.getMessage(), "Error!", javax.swing.JOptionPane.ERROR_MESSAGE);
javax.swing.JOptionPane.showMessageDialog(this, strMsg);

Recoger información del mouse

Podemos conseguir información sobre la posición actual del mouse mediante el método estático java.awt.MouseInfo.getPointerInfo().getLocation(), pero este método no nos dará la posición relativa al Frame, sino la total respecto a la pantalla.

Cambiar el tipo de cursor

En un control veremos el método “setCursor”, a este hay que pasarle un objeto Cursor que debemos crear con un integer. Este integer lo sacaremos de las constantes de la clase Cursor. Mira como se cambia un cursor de flecha a uno de mano: this.setCursor(new Cursor(Cursor.HAND_CURSOR));

Hacer el cursor invisible

Las próximas líneas de código simulan un cursor de mouse invisible, para ello lo que hacen es crear un nuevo cursor mediante una imágen vacía y asignarla al frame.

	Toolkit tk = Toolkit.getDefaultToolkit();
	Cursor invisCursor = tk.createCustomCursor(tk.createImage(""),new Point(),null);
	setCursor(invisCursor); 

Utilizar un timer

javax.swing.Timer es una clase que nos permite implementar un timer, es muy intuitiva, con métodos como start, stop, setInteval… Sólo decir que en el constructor tendrás que pasarle un objeto que implemente la interface ActionListener, en su método ActionPerformed podrás codificar el toque de relog que toque.

Crear un formulario modal

Existe la clase javax.swing.JDialog, si heredas de ella puedes utilizar un constructor suyo al cual le pasas un boolean que indica si es o no modal.

public class optionsDialog extends javax.swing.JDialog {
    public optionsDialog(java.awt.Frame parent) {
        super(parent, "Opciones", true);
        initComponents();
    }
...

Luego manejarás la ventana mediante el método setVisible.

Mostrar las ventanas de Abrir\Guardar fichero

Para mostrar estas ventanas tenemos que crear un objeto JFileChooser:

javax.swing.JFileChooser jfc = new JFileChooser();

Este contiene los métodos showOpenDialog y showOpenDialog que son los encargados de mostrar estas ventanas. Una vez son mostradas el programa no continuará hasta que el usuario no seleccione un fichero o aprete el botón Cancelar. Si el usuario escoge un fichero este método devuelve un integer con valor 0, el fichero escogido lo devolverá el método getSelectedFile del JFileChooser.

if (jfc.showOpenDialog(this) == 0) {
      java.io.File f = jfc.getSelectedFile();
      ...

Añadir scrolls a un control

Existe un control especial llamado javax.swing.JScrollPane, este permite añadir barras de scroll a otros controles como son los cuadros de textos o las listas. Se añade al formulario como se añadiría otro control cualquiera, justo en la posición donde se añadirá el control al cual deseas añadir barras de scroll. Luego, le pasas al método setView de su ViewPort (para acceder a esta llama al getViewport) el control escogido.

JList dataList;
...
JScrollPane scrollPane = new JScrollPane();
scrollPane.getViewport().setView(dataList);

Tips