Vous êtes sur la page 1sur 6

USOS DE ACTIONLISTENER

Los componentes java (JButton, JTextField, etc) y algunas clases que no lo son (como TableModel, ListModel, etc) permiten que nos "suscribamos" a eventos que pasan en ellos, de forma que cuando ocurre este evento, el componente nos avisa. Por ejemplo, podemos estar interesados en cundo se pulsa un botn, cuando un componente gana el foco, cuando pasa el ratn por encima, cundo se cierra una ventana, etc. Para enterarnos de todos estos eventos, los componentes tienen mtodos del estilo add...Listener() donde los puntos suspensivos, de alguna forma, representan el nombre del tipo de evento. As, por ejemplo, los componentes pueden tener mtodos addActionListener(), addMouseListener(), addWindowListener(), etc. Lo que se comenta aqu valdr para todos ellos, pero nos centraremos en el ActionListener. Cuando usamos el addActionListener() de un componente, nos estamos suscribiendo a la "accin tpica" o que java considera ms importante para ese componente. Por ejemplo, la accin ms tpica de un JButton es pulsarlo. Para un JTextField, java considera que es pulsar <INTRO> indicando que hemos terminado de escribir el texto, para un JComboBox es seleccionar una opcin, etc. Cuando llamamos al addActionListener() de cualquiera de estos componentes, nos estamos suscribiendo a la accin ms "tpica" de ese componente. Como parmetro, debemos pasar una clase que implemente ActionListner. Por tanto, debemos hacer una clase que implemente la interface ActionListener. Hay muchas formas de hacer esto y vamos a verlas. FORMA BSICA Una forma es hacer una clase en un fichero java que implemente ActionListener.
public class MiClase implements ActionListener { public void actionPerformed (ActionEvent e) { // cdigo que queremos que se ejecute cuando tiene lugar la accin. // la pulsacin del botn, el <INTRO> en el JTextField, eleccin en el JComboBox, etc. }

Rubn Arriagada Daz Ingeniero en Computacin e Informtica Docente IPLA - Temuco

Luego, simplemente tenemos que aadir esta clase al componente java usando su mtodo addActionListener().
JButton boton = new JButton ("Pulsame"); MiClase elListener = new MiClase(); boton.addActionListener (elListener);

Ya est, cuando se pulse el botn, java llamar a nuestro mtodo actionPerformed() de nuestra clase MiClase. Este mtodo no se suele usar casi nunca, puesto que es bastante engorroso hacerse una clase para cada uno de los componentes java que tengamos en la ventana que hagan algo. Otra pega es que la clase es totalmente independiente, por lo que no tenemos acceso a los mtodos de ninguna otra clase, salvo que hagamos algo para pasrselas y hacrselas accesibles. UNA CLASE INTERNA Otra forma es hacer una clase interna dentro de otra clase. Por ejemplo, si nuestra clase es una clase que hereda de JFrame y tiene botones, podemos hacerlo as
public class MiVentana extends JFrame { public MiVentana() { JButton boton = new JButton ("Pulsame"); MiClase elListener = new MiClase(); boton.addActionListener (elListener); } public void pulsado() { System.out.println("Pulsado el botn"); } ... // Esta es la clase interna. Est definida DENTRO de MiVentana public class MiClase implements ActionListener { public void actionPerformed (ActionEvent e) { pulsado(); } } } Rubn Arriagada Daz Ingeniero en Computacin e Informtica Docente IPLA - Temuco

Este mtodo sigue presentando el inconveniente de que hay que hacer una clase completa para cada componente java que tengamos en la ventana que queramos que haga algo. La ventaja es que desde esta clase interna s podemos acceder a mtodos de la clase externa a la que pertenece. Como vemos en el ejemplo, desde MiClase podemos llamar al mtodo pulsado() de la clase MiVentana. HACER QUE LA CLASE PRINCIPAL IMPLEMENTE ACTIONLISTENER Otra forma que s se usa a veces es hacer que la clase principal implemente ActionListener as.
public class MiVentana extends JFrame implements ActionListener { public MiVentana() { JButton boton = new JButton ("Pulsame"); MiClase elListener = new MiClase(); boton.addActionListener (this); } public void actionPerformed (ActionEvent e) { System.out.println("Pulsado"); } }

Aqu ahorramos hacer una clase nueva y tenemos accesibles todos los mtodos de la clase principal. Esta opcin es muy cmoda si tenemos pocos componentes a los que aadir el listener. CLASE ANNIMA La opcin que ms se usa es la de hacer la clase "sobre la marcha". El cdigo es este
public class MiVentana extends JFrame { public MiVentana() { JButton boton = new JButton ("Pulsame"); MiClase elListener = new MiClase(); final int unaVariable=3; boton.addActionListener (new ActionListener() { public void actionPerformed (ActionEvent e) Rubn Arriagada Daz Ingeniero en Computacin e Informtica Docente IPLA - Temuco

{ pulsado(); // Aqu est accesible unaVariable System.out.println(unaVariable); } }); } public void pulsado() { System.out.println("Pulsado el botn"); } }

De esta forma, cuando compilemos se crear algo parecido a un fichero


MiVentana$1.class

Ese es el fichero de la clase annima. Esa clase existe, pero no tenemos el cdigo fuente separado. Aqu tambin tenemos acceso a todo lo de la clase MiVentana. Incluso tenemos acceso a las variables locales y parmetros del mtodo de la clase principal donde hayamos aadido el listener. En este caso, a las variables locales y parmetros del constructor. La pega de acceder a estas variables locales es que cuando se pulse en botn puede que ya no existan, as que si las usamos directamente, java no nos dejar compilar. Para que esto no pase, debemos declarar los parmetros y variables locales que queramos usar como final. En el cdigo se ve el caso con la variable entera unaVariable. Un equvoco habitual es que esta clase interna NO es la clase MiVentana. Por ello, this no hace referencia a MiVentana, sino a la clase interna. Si queremos acceder a MiVentana con this (aunque realmente no hace falta), debemos hacer esto
public void actionPerformed (ActionEvent e) { MiVentana.this.pulsado(); }

Rubn Arriagada Daz Ingeniero en Computacin e Informtica Docente IPLA - Temuco

DISTINGUIR QU BOTN CAUSA LA ACCIN Cuando nos decidimos a hacer una clase, suele ser habitual querer aprovechar la clase para varios botones. En el mtodo actionPerformed() de esa clase se nos pasa un ActionEvent. Con este ActionEvent podemos obtener informacin sobre quin es el que ha provocado el evento. Object fuente = event.getSource(); Este mtodo nos devuelve el componente java (JButton, JTextField, etc) que ha provocado el evento. Si la clase est aadida, por ejemplo a boton1, boton2 y boton3, en el mtodo actionPerformed() podemos hacer algo como esto
public void actionPerformed (ActionEvent e) { Object fuente = e.getSource(); if (fuente==boton1) metodoParaBoton1(); else if (fuente==boton2) metodoParaBoton2(); else if (fuente==boton3) metodoParaBoton3(); }

Otra opcin interesante, es decirle al botn cual es su "comando". Se hace as


boton.setActionCommand("Borra"); // Borra es un texto cualquiera, que NO se ve en el botn

Luego, en el ActionEvent, podemos obtener el "comando" del componente que ha provocado el evento.
public void actionPerformed (ActionEvent e) { String comando = e.getActionCommand(); if (comando.equals("Borra")) metodoParaBorra(); else if (comando.equals("Crea")) metodoParaCrea(); else if (comando.equals("Modifica")) metodoParaModifica(); }

Este mtodo tiene la ventaja, adems de ser ms claro, que permite que aadamos el mismo comando a varios botones o componentes y todos ellos harn lo mismo. Por
Rubn Arriagada Daz Ingeniero en Computacin e Informtica Docente IPLA - Temuco

ejemplo, imagina que tenemos un men en el que una de las opciones es "Borra" y una barra de herramientas rpida en la que tenemos un botn que tambin "Borra". Aadiendo el mismo ActionListener a ambos, men y botn, la accin que se ejecutar es la misma. Si hicieramos esto con el e.getSource(), deberamos poner un if con un OR.
if (( e.getSource()==boton ) || (e.getSource()==opcionMenu ))

...

Rubn Arriagada Daz Ingeniero en Computacin e Informtica Docente IPLA - Temuco

Vous aimerez peut-être aussi