Respuesta a las acciones del usuario sobre un grupo de controles (botones)

prev.gif (997 bytes)chapter.gif (1105 bytes)home.gif (1232 bytes)next.gif (1211 bytes)

Sucesos (events)

La información acerca del suceso

Respuesta a las acciones del usuario sobre un conjunto de tres botones

Tres funciones respuesta

Un único objeto maneja los sucesos de un grupo de botones


La información acerca del suceso

En el estudio de la función respuesta a la acción de pulsar sobre un botón, o de hacer doble-clic sobre un elemento de una lista, el objeto ev de la clase ActionEvent, nos proporciona información acerca del suceso que se ha producido, nos dice qué control ha generado el suceso. Por ejemplo, podemos saber mediante la función miembro getSource si el suceso procede de la acción sobre un botón, de un control lista, o de un control de edición, etc.

En el código de la función respuesta actionPerformed, podemos saber si el control sobre el que se ha actuado es una instancia de la clase Button mediante el operador  instanceof

	Object control=ev.getSource();
	if(control instanceof Button){
		System.out.println("Se ha pulsado un botón");
	}

Si hay varias botones, podemos saber cual de ellos ha sido pulsado mediante equals.

	Object control=ev.getSource();
	if(control.equals(btnAceptar){
		System.out.println("Se ha pulsado el botón Aceptar");
	}

Mediante getAccionCommand obtenemos el nombre (etiqueta) del botón. Podemos saber si se ha pulsado sobre un botón titulado "Rojo".

	String nombre=ev.getActionCommand();
	if(nombre.equals("Rojo"){
		System.out.println("Se ha pulsado el botón Rojo");
	}

Como veremos más adelante, dependiendo del tipo de suceso, la información está encapsulada en distintas clases, que proporcionan la información que interesa al usuario. Así, la clase AdjustementEvent encapsula toda la información referente a las acciones sobre la barra de desplazamiento. Del objeto ev podemos extraer mediante la función miembro getValue, el valor al que equivale la posición del dedo en la barra de desplazamiento.

  void sbRadio_adjustmentValueChanged(AdjustmentEvent ev) {
     radio=ev.getValue();
     repaint();
  }

La clase ItemEvent encapsula la información referente a las acciones sobre un control lista, o un control selección. La función miembro getItem obtiene de un objeto ev de dicha clase el elemento que ha sido seleccionado. getItem devuelve un objeto de la clase base Object, que puede ser necesario promocionar (casting) a un objeto de la clase adecuada.

En el caso de un control selección (Choice) comparamos mediante equals, el objeto devuelto por getItem (el elemento seleccionado) con cada uno de los nombres de los elementos de dicho control.

    void chComida_itemStateChanged(ItemEvent ev) {
        if((ev.getItem()).equals("Desayuno")){
		//...
        }
    }

En el caso de un control lista (List) el objeto de la clase Object devuelto por getItem, es promocionado a Integer. El objeto de la clase Integer es convertido en un número entero (el índice del elemento seleccionado) mediante la función intValue.

    void lista_itemStateChanged(ItemEvent e) {
      indice=((Integer)e.getItem()).intValue();
      //...
    }

Respuesta a las acciones del usuario sobre un conjunto de tres botones

disco.gif (1035 bytes)botones2: BotonesApplet2.java

Propósito

Ya estudiamos la respuesta a la acción de pulsar sobre un botón. Diseñamos un applet contiene un conjunto de tres botones situados en la parte superior del applet. El nombre de los botones es el de los colores primarios: azul, verde y rojo.  Al pulsar un botón se pinta un rectángulo de dicho color.

Diseño

Crear el applet, situar tres botones en la parte superior.

Cambiar sus propiedades name y label en sus respectivas hojas de propiedades

Establecer FlowLayout, como gestor de diseño del applet. Cambiar la propiedad hgap para separar horizontalmente los botones.

Crear un array colores de objetos de la clase Color con los tres colores primerios: rojo, verde y azul.

  final Color[] colores={Color.red, Color.green, Color.blue};

Redefinir la función paint para pintar un rectángulo

Respuesta a las acciones del usuario

Nuestra primera intención será la de seleccionar en el panel del diseño cada uno de los botones y en sus correspondientes paneles Events se hace doble-clic sobre el editor asociado a actionPerformed. A continuación, veremos cómo se puede elaborar una respuesta única a las acciones sobre un conjunto de controles que responden de forma semejante.

 

Tres funciones respuesta

El IDE de JBuilder genera el código que crea tres objetos de otras tanteas clases anónimas y asocia cada uno de ellos con el correspondiente botón mediante addActionListener (Anonymous adapter)

    btnRojo.setLabel("Rojo");
        btnRojo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnRojo_actionPerformed(e);
            }
        });
    btnVerde.setLabel("Verde");
        btnVerde.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnVerde_actionPerformed(e);
            }
        });
    btnAzul.setLabel("Azul");
        btnAzul.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btnAzul_actionPerformed(e);
            }
        });

Ahora, solamente nos queda definir cada una de las funciones respuesta.

    void btnRojo_actionPerformed(ActionEvent e) {
        indice=0;
        repaint();
    }
    void btnVerde_actionPerformed(ActionEvent e) {
        indice=1;
        repaint();
    }
    void btnAzul_actionPerformed(ActionEvent e) {
        indice=2;
        repaint();
    }

A continuación, redefinimos la función paint, para dibujar un rectángulo del color seleccionado al pulsar el botón correspondiente.

  public void paint(Graphics g){
    g.setColor(colores[indice]);
    g.fillRect(20, 50, 100, 50);
  }

Ahora bien, se puede observar que en las funciones respuesta, el código está repetido. Para escribir un código más compacto, definimos una única función respuesta para todos los botones denominada botones_actionPerformed. Obtenemos el botón que ha sido pulsado, un objeto de la clase base Object) mediante getSource. Alternativamente, se puede obtener el botón que ha sido pulsado mediante getActionCommand, la comparación se establece entonces con el título o etiqueta de los botones. Véase el primer apartado, información acerca del susceso.

   void botones_actionPerformed(ActionEvent e) {
        Object boton=e.getSource();
        if(boton.equals(btnRojo)){
            indice=0;
        }else if(boton.equals(btnVerde)){
            indice=1;
        }else{
             indice=2;
        }
        repaint();
    }

El código fuente completo de este ejemplo, es el siguiente

package botones2;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class BotonesApplet2 extends Applet {
  Button btnRojo = new Button();
  Button btnVerde = new Button();
  Button btnAzul = new Button();
  FlowLayout flowLayout1 = new FlowLayout();
  final Color[] colores={Color.red, Color.green, Color.blue};
  int indice;

  public void init() {
      btnRojo.setLabel("Rojo");
        btnRojo.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                botones_actionPerformed(e);
            }
        });
    btnVerde.setLabel("Verde");
        btnVerde.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                botones_actionPerformed(e);
            }
        });
    btnAzul.setLabel("Azul");
        btnAzul.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                botones_actionPerformed(e);
            }
        });
    flowLayout1.setHgap(10);
    this.setLayout(flowLayout1);
    this.add(btnRojo, null);
    this.add(btnVerde, null);
    this.add(btnAzul, null);
  }
 
  public void paint(Graphics g){
    g.setColor(colores[indice]);
    g.fillRect(20, 50, 100, 50);
  }

   void botones_actionPerformed(ActionEvent e) {
        Object boton=e.getSource();
        if(boton.equals(btnRojo)){
            indice=0;
        }else if(boton.equals(btnVerde)){
            indice=1;
        }else{
             indice=2;
        }
        repaint();
    }
}

 

Un único objeto maneja los sucesos de un grupo de botones

disco.gif (1035 bytes)botones1: BotonesApplet1.java

Podemos simplificar aún más el código, podemos pensar en un único objeto accion de una clase que implemente el interface ActionListener esté interesado en las acciones sobre los tres botones. Emplearemos el otro modo que tiene JBuilder de generar el código (Standard adapter) que maneja los sucesos.

Definimos una clase que implemente el interface ActionListener y defina la función actionPerformed.

class AccionBotones implements ActionListener{
    private BotonesApplet1 applet;
    public AccionBotones(BotonesApplet1 applet){
        this.applet=applet;
    }
    public void actionPerformed(ActionEvent ev){
        applet.botones_actionPerformed(ev);
    }
 }

Creamos un objeto accion de la clase AccionBotones y le pasamos el applet. this inicializa el miembro dato applet de la clase AccionBotones. Desde dicho objeto llamamos a la función respuesta denominada botones_actionPerformed, en la definición de actionPerformed.

    AccionBotones accion=new AccionBotones(this);

Asociamos mediante la función addActionListener cada uno de los botones con el objeto accion que registra las acciones sobre dichos botones.

    btnRojo.addActionListener(accion);
    btnVerde.addActionListener(accion);
    btnAzul.addActionListener(accion);

Definimos la función respuesta botones_actionPerformed, la tarea a realizar, cuando se pulsa sobre alguno de los botones de la misma forma que en el ejemplo anterior.

El código completo de este ejemplo, es el siguiente

package botones1;

import java.awt.*;
import java.awt.event.*;
import java.applet.*;

public class BotonesApplet1 extends Applet {
  Button btnRojo = new Button();
  Button btnVerde = new Button();
  Button btnAzul = new Button();
  FlowLayout flowLayout1 = new FlowLayout();
  final Color[] colores={Color.red, Color.green, Color.blue};
  int indice;
 
  public void init() {
    btnRojo.setLabel("Rojo");
    btnVerde.setLabel("Verde");
    btnAzul.setLabel("Azul");
    AccionBotones accion=new AccionBotones(this);
    btnRojo.addActionListener(accion);
    btnVerde.addActionListener(accion);
    btnAzul.addActionListener(accion);
    flowLayout1.setHgap(10);
    this.setLayout(flowLayout1);
    this.add(btnRojo, null);
    this.add(btnVerde, null);
    this.add(btnAzul, null);
  }

  public void botones_actionPerformed(ActionEvent ev){
        Object boton=ev.getSource();
        if(boton.equals(btnRojo)){
            indice=0;
        }else if(boton.equals(btnVerde)){
            indice=1;
        }else{
             indice=2;
        }
        repaint();
  }

  public void paint(Graphics g){
    g.setColor(colores[indice]);
    g.fillRect(20, 50, 100, 50);
  }
}

class AccionBotones implements ActionListener{
    private BotonesApplet1 applet;
    public AccionBotones(BotonesApplet1 applet){
        this.applet=applet;
    }
    public void actionPerformed(ActionEvent ev){
        applet.botones_actionPerformed(ev);
    }
}