Cuando el usuario realiza una acción en la interfaz gráfica (pulsar el botón del ratón o presionar una tecla), se genera un evento. Los eventos son objetos que describen lo que ha ocurrido. Existen numerosas clases de eventos diferentes para describir las distintas categorías de acciones de los usuarios.
En la siguiente imagen se muestra una vista abstracta del modelo de delegación de eventos. Cuando un usuario hace clic en un botón de la interfaz gráfica, JVM crea un objeto evento que se envía al controlador de eventos (también conocido como manejador de eventos) correspondiente a ese botón mediante una llamada al método actionPerformed.

La fuente de un evento es aquella que genera el evento. Por ejemplo, pulsar un botón del ratón sobre un componente JButton genera una instancia de ActionEvent que tiene ese botón como fuente. La instancia de ActionEvent es un objeto que contiene información sobre el evento que acaba de producirse.
El modelo de delegación de eventos se implementó con la versión 1.1 del kit de desarrollo de Java (JDK). Con este modelo, los eventos se envían al componente desde el que se ha originado el evento, pero depende de cada componente su propagación a una o más clases registradas denominadas receptores de eventos (listeners). Estos receptores contienen controladores que reciben el evento y lo procesan. De esta forma, el controlador de eventos puede estar situado en un objeto independiente del componente. Los receptores de eventos son clases que implementan la interfaz EventListener.
En el siguiente ejemplo se muestra la forma de crear un marco (JFrame) sencillo que sólo contiene un botón (JButton).
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
package delegacioneventos; import javax.swing.*; import java.awt.*; public class TestBoton { private JFrame f; private JButton b; public TestBoton() { f = new JFrame("Test"); b = new JButton("Pulsar"); b.setActionCommand("ButtonPressed"); } public void launchFrame() { b.addActionListener(new ButtonHandler()); f.add(b, BorderLayout.CENTER); f.pack(); f.setVisible(true); } public static void main(String args[]) { TestBoton guiApp = new TestBoton(); guiApp.launchFrame(); } } |
La clase ButtonHandler mostrada a continuación es la clase del controlador en el que se delega el evento.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
package delegacioneventos; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class ButtonHandler implements ActionListener { public void actionPerformed(ActionEvent e) { System.out.println("Se ha realizado una acción"); System.out.println("El comando del botón es: " + e.getActionCommand()); } } |
El resultado de la ejecución es el siguiente:

CATEGORÍAS DE EVENTOS
El mecanismo descrito para recibir eventos de los componentes se ha ilustrado en el contexto de un único tipo de evento.
| Interfaz | Métodos |
|---|---|
| ActionListener | actionPerformed(ActionEvent) |
| AdjustmentListener | adjustmentValueChanged(AdjustmentEvent) |
| ComponentListener ComponentAdapter |
componentHidden(componentEvent) componentShown(componentEvent) componentMoved(componentEvent) componentResized(componentEvent) |
| FocusListener FocusAdapter |
focusGained(FocusEvent) focusLost(FocusEvent) |
| KeyListener KeyAdapter |
keyPressed(KeyEvent) keyReleased(KeyEvent) keyTyped(KeyEvent) |
| MouseListener MouseAdapter |
mouseClicked(MouseEvent) mouseEntered(MouseEvent) mouseExited(MouseEvent) mousePressed(MouseEvent) mouseReleased(MouseEvent) |
| MouseMotionListener MouseMotionAdapter |
mouseDragged(MouseEvent) mouseMoved(MouseEvent) |
| WindowListener WindowAdapter |
windowOpened(WindowEvent) windowClosing(WindowEvent) windowClosed(WindowEvent) windowActivated(WindowEvent) windowDeactivated(WindowEvent) windowIconified(WindowEvent) windowDeiconified(WindowEvent) |
| ItemListener | itemStateChanged(itemEvent) |
| TextListener | textValueChanged(TextEvent) |
CONTROL DE EVENTOS MEDIANTE CLASES INTERNAS
En el siguiente ejemplo se muestra la forma de crear controladores de eventos como clases internas. El uso de clases internas para manejar eventos permite acceder a los datos privados de la clase externa.
Clase que captura el evento
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
package eventosconclasesinternas; import java.awt.event.*; public class MouseClickHandler extends MouseAdapter { // Sólo necesitamos el método mouseClicked, así que usamos // un adaptador para no tener que escribir // todos los métodos de control de eventos @Override public void mouseClicked(MouseEvent e) { // Realiza acciones al pulsar el botón .... } } |
Clase interna
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
package eventosconclasesinternas; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class TestInner { private JFrame f; private JTextField tf; public TestInner() { f = new JFrame("Ejemplo de clases internas"); tf = new JTextField(30); } class MyMouseMotionListener extends MouseMotionAdapter { public void mouseDragged(MouseEvent e) { String s = "Arrastre del ratón: X = " + e.getX() + " Y = " + e.getY(); tf.setText(s); } } public void launchFrame() { JLabel label = new JLabel("Hacer clic y arrastrar el ratón"); f.add(label, BorderLayout.NORTH); f.add(tf, BorderLayout.SOUTH); // Agrega un Listener que utiliza una clase interna f.addMouseMotionListener(new MyMouseMotionListener()); f.addMouseListener(new MouseClickHandler()); // Define el tamaño del marco y lo hace visible f.setSize(300, 200); f.setVisible(true); } public static void main(String args[]) { TestInner obj = new TestInner(); obj.launchFrame(); } } |
Al pulsar y arrastrar el ratón se muestran las coordenadas donde se encuentre el cursor.

CONTROL DE EVENTOS MEDIANTE CLASES ANÓNIMAS
Es posible incluir una definición de clase completa dentro del ámbito de una expresión. Esta fórmula permite definir lo que se denomina una clase interna anónima y crear la instancia al mismo tiempo.
La compilación en Java de una clase anónima genera un archivo del tipo TestAnonymous$1.class.
Veamos el mismo ejemplo realizado anteriormente con clase interna, ahora con clase anónima.
Evento con clase anónima
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package eventosconclasesanónimas; import java.awt.*; import java.awt.event.*; public class TestAnonymous { private Frame f; private TextField tf; public TestAnonymous() { f = new Frame("Anonymous classes example"); tf = new TextField(30); } public void launchFrame() { Label label = new Label("Click and drag the mouse"); f.add(label, BorderLayout.NORTH); f.add(tf, BorderLayout.SOUTH); // Añadimos el listener que utiliza la clase anonima f.addMouseMotionListener(new MouseMotionAdapter() { public void mouseDragged(MouseEvent e) { String s = "Mouse dragging: X = " + e.getX() + " Y = " + e.getY(); tf.setText(s); } }); // Observar que cerramos los parentesis f.addMouseListener(new MouseClickHandler()); f.setSize(300, 200); f.setVisible(true); } public static void main(String args[]) { TestAnonymous obj = new TestAnonymous(); obj.launchFrame(); } } |