domingo, 27 de marzo de 2016

025.- Creación de Eventos en General Desde Código - Java y NetBeans


EVENTOS DESDE CÓDIGO
CONSIDERACIONES GENERALES

Se finalizará el estudio de los eventos desde código, planteando de forma general el código necesario para programarlos.

A la hora de programar eventos sobre un componente concreto, será necesario tener en cuenta lo siguiente:

-        Primero hay que enlazar el componente con el oyente o adaptador correspondiente al evento.

-        El oyente o adaptador contendrá aquellos eventos que interesen programar.

-        Cada evento tiene un parámetro asociado con información sobre el evento.

-        Cada evento realiza una llamada a un método y es en este método donde se programa la respuesta al evento.


La sintaxis general de programación de eventos es la siguiente:



Componente.MetodoParaAñadirOyente(new TipoOyente() {

     public void evento1(TipoEvento evt) {
          LlamadaAProcedimiento1(evt);
     }

     public void evento2(TipoEvento evt) {
          LlamadaAProcedimiento2(evt);
     }

     ...otros eventos...
});



Para poder programar un evento es necesario conocer lo siguiente:

-        El componente sobre el que se programará.
-        El tipo oyente o adaptador al que pertenece el evento.
-        El método usado para asignar el oyente al componente.
-        El nombre del evento.
-        El tipo de evento para el parámetro.




EJEMPLO 1 (EVENTOS DEL RATÓN):


Los eventos de ratón son: mouseEntered, mouseExited, mousePressed, mouseReleased, mouseClicked.

Pertenecen al adaptador MouseAdapter.

El adaptador se asigna al componente con el método addMouseListener.

Los métodos llevan como parámetro un objeto del tipo MouseEvent.

Conociendo esto, si queremos programar los eventos del ratón de una etiqueta llamada etiMensaje, sólo tenemos que hacer lo siguiente:



etiMensaje.addMouseListener(new MouseAdapter() {

     public void mouseEntered(MouseEvent evt) {
          etiMensajeMouseEntered(evt);
     }

     public void mouseExited(MouseEvent evt) {
          etiMensajeMouseExited(evt);
     }

     public void mousePressed(MouseEvent evt) {
          etiMensajeMousePressed(evt);
     }

     public void mouseReleased(MouseEvent evt) {
          etiMensajeMouseReleased(evt);
     }

     public void mouseClicked(MouseEvent evt) {
          etiMensajeMouseClicked(evt);
     }

});



EJEMPLO 2 (EVENTOS DEL TECLADO):


Los eventos de teclado controlan las pulsaciones de tecla. Entre ellos, podemos mencionar a los siguientes:

-        keyPressed, que define la pulsación de una tecla.
-        keyReleased, que define el momento en que se suelta una tecla.
-        keyTyped, que define el pulsar-soltar una tecla.

Los eventos de teclado pertenecen al adaptador KeyAdapter.

El adaptador anterior se asigna a un componente a través del método addKeyListener.

Los eventos de teclado llevan como parámetro un objeto del tipo KeyEvent.

Sabiendo lo anterior, si se quisieran programar los eventos de teclado de un cuadro de texto llamado txtDato el código necesario sería el siguiente:


txtDato.addKeyListener(new KeyAdapter() {

     public void keyPressed(KeyEvent evt) {
          txtDatoKeyPressed(evt);
     }

     public void keyReleased(KeyEvent evt) {
          txtDatoKeyReleased(evt);
     }

     public void keyTyped(KeyEvent evt) {
          txtDatoKeyTyped(evt);
     }

});



Como puedes observar, la programación de eventos siempre se hace de la misma forma, solo tienes que conocer el adaptador/oyente, el método para asignar dicho adaptador/oyente, el nombre de los eventos, y el tipo de objeto que llevan como parámetro.

Sabiendo estos datos, la programación siempre se hace igual.

El problema que se plantea en cambio es el siguiente:

Si surge un nuevo evento YY el cual quiero usar desde código, ¿cómo puedo saber cuál es su adaptador/oyente, el método para asignar dicho adaptador/oyente al componente, y el tipo de datos del parámetro?

Para este caso, se aconseja crear un proyecto de prueba desde la ventana de diseño y asignar el evento YY que se quiere estudiar a un componente. Luego simplemente hay que analizar el código generado por el NetBeans.




CONCLUSIONES:

Para programar desde código un evento es necesario conocer lo siguiente:

- El nombre del evento / eventos del mismo grupo.
- El oyente/adaptador al que pertenece el evento / eventos.
- El método para asignar el oyente/adaptador al componente sobre el que actúa el evento.
- El tipo de datos de objeto recibido como parámetro por el evento.

Conociendo estos datos, la programación siempre se hace igual:


Componente.MetodoParaAñadirOyente(new NombreOyenteAdaptador() {

     public void nombreEvento1(TipoDatoParametro evt) {
          LlamadaAProcedimientoEvento1(evt);
     }

     public void nombreEvento2(TipoDatoParametro evt) {
          LlamadaAProcedimientoEvento2(evt);
     }
});



Se puede aprender mucho sobre los eventos asociándolos desde diseño y luego mirando en el código generado.

024.- Creación de Eventos del Ratón Desde Código - Java y NetBeans


EVENTOS DEL RATÓN DESDE CÓDIGO:

Se estudió en el post anterior la forma de programar eventos desde código. Concretamente se estudió como programar eventos de acción. En esta hoja se estudiará como programar eventos de ratón.

Los eventos de ratón son los siguientes:

-        mouseEntered
o   Indica que el puntero del ratón entró en la superficie del elemento (etiqueta, botón, etc)
-        mouseExited
o   Indica que el puntero del ratón salió de la superficie del elemento (etiqueta, botón, etc)
-        mousePressed
o   Indica que un botón del ratón ha sido presionado sobre el elemento.
-        mouseReleased
o   Indica que un botón del ratón ha sido soltado sobre el elemento.
-        mouseClicked
o   Indica que se ha pulsado y soltado un botón del ratón.

Como se dijo en la hoja anterior, todos los eventos pertenecen a un objeto “oyente” o “adaptador”. En este caso concreto, todos los eventos del ratón pertenecen a un objeto “adaptador” llamado MouseAdapter.

Cada uno de los eventos se programará dentro del adaptador MouseAdapter. Cada evento es en realidad un procedimiento que recibe un parámetro con información sobre el evento. Este parámetro, en el caso de los eventos del ratón, es del tipo MouseEvent.

Cada evento a su vez hace una llamada a un método, y es en este procedimiento donde realmente se programa la respuesta al evento.

Todo esto resulta complicado al principio, pero verás que en realidad siempre es igual. Solo hay que conocer el nombre de cada evento, el adaptador u oyente al que pertenece y el tipo de parámetro que recibe cada evento.




COMO ENLAZAR EVENTOS DE RATÓN CON UN COMPONENTE:


Supongamos que tenemos un componente (botón, etiqueta, etc...) llamado YYY.

Si queremos asociarle eventos de ratón, tendremos que añadir el siguiente código dentro del método constructor:

YYY.addMouseListener(new MouseAdapter() {

     public void mouseEntered(MouseEvent evt) {
          YYYMouseEntered(evt);
     }

     public void mouseExited(MouseEvent evt) {
          YYYMouseExited(evt);
     }

     public void mousePressed(MouseEvent evt) {
          YYYMousePressed(evt);
     }

     public void mouseReleased(MouseEvent evt) {
          YYYMouseReleased(evt);
     }

     public void mouseClicked(MouseEvent evt) {
          YYYMouseClicked(evt);
     }

});


Veamos este mismo código comentado:





EJERCICIO:

  1. Crea un nuevo proyecto en NetBeans.

  1. Accede al código del proyecto.



  1. Inserta una llamada dentro del método constructor a un método creacionVentana de la siguiente forma:



  1. La ventana va a contener dos etiquetas, que tendremos que declarar en la zona de variables globales:



  1. Ahora vamos a diseñar la ventana. Introduce el siguiente código dentro del procedimiento creacionVentana:



  1. Ejecuta ya el programa para observar el resultado de nuestro diseño. El aspecto debe ser el siguiente:



  1. El objetivo del programa es simple. Queremos que al entrar el puntero del ratón dentro de la superficie de la etiqueta azul, aparezca un mensaje en la otra etiqueta indicándolo. También queremos que aparezca un mensaje cuando sale el puntero del ratón de la etiqueta. Y también al pulsar un botón del ratón sobre dicha etiqueta.

  1. Para hacer esto, necesitamos crear un MouseAdapter que contenga los siguientes eventos: mouseEntered, mouseExited y mousePressed. Observa que no es necesario que contenga el mouseReleased ni el mouseClicked.

Luego, el MouseAdapter se asignará a la etiqueta azul etiColor.

  1. Primero programaremos el enlace del adaptador MouseAdapter con la etiqueta etiColor. Programa al final del método creacionVentana lo siguiente:



  1. Observa el código:

    1. Se añade un MouseAdapter al objeto etiColor.

    1. El MouseAdapter que se añade solo contiene los tres eventos que necesitamos: mouseEntered, mouseExited y mousePressed.

    1. Será necesario añadir imports para las clases MouseAdapter y MouseEvent.

    1. Es normal que las llamadas a los procedimientos de cada evento den error (subrayado con líneas rojas) ya que todavía no han sido programados.

  1. Ahora se programará cada procedimiento que es llamado desde cada evento. Recuerda que esto debe hacerse fuera del método creacionVentana. Aquí tienes lo que debes programar:



  1. Ahora ya puedes ejecutar el programa y comprobar lo que sucede cuando interactúas con el ratón sobre la etiqueta de color azul.


  1. Vamos a añadir una pequeña mejora que nos servirá para estudiar ese objeto llamado evt del tipo MouseEvent que llevan todos los eventos de ratón como parámetro.

Se dijo antes que este parámetro contiene información sobre la acción del ratón. Por ejemplo, nos puede servir para saber cuantas veces se pulsó el ratón, con qué botón, etc. Aprovecharemos este parámetro para indicar qué botón del ratón es el que se ha pulsado sobre la etiqueta.

Cambia el método etiColorMousePressed y déjalo de la siguiente forma:



  1. En el código anterior aprovechamos los métodos que tiene el objeto evt para averiguar que botón se ha pulsado. Usamos el método getButton que nos dice el botón pulsado. Aprovechamos las constantes de la clase MouseEvent para saber si se pulsó el botón izquierdo, central o derecho.

  1. Ejecuta el programa y comprueba el funcionamiento.


CONCLUSIONES:

Hay grupos de eventos que pertenecen a un mismo oyente o adaptador. Por ejemplo, los eventos de ratón pertenecen al adaptador llamado MouseAdapter.

Si se quiere asignar eventos de ratón a un componente YYY, hay que usar el siguiente código:

YYY.addMouseListener(new MouseAdapter() {
    
public void mouseEntered(MouseEvent evt) {
          YYYMouseEvent(evt);
     }

     ... otros eventos de ratón ...
});


Ten en cuenta que solo añades al adaptador aquellos eventos que necesites.

Cada evento de ratón lleva como parámetro un objeto evt del tipo MouseEvent que contiene información sobre el evento ocurrido (qué botón del ratón se pulsó, cuantas veces, etc.).


023.- Creación de Eventos Desde Código - Java y NetBeans


Creación de eventos desde código

La ventana de diseño de NetBeans nos permite crear cada componente, colocarlo en la ventana y acceder a los eventos que necesitemos fácilmente para programar en ellos las acciones que se tengan que realizar.

Sin embargo, si el diseño de la ventana se ha realizado directamente desde código, será necesario crear también desde código los distintos eventos a usar, y asociarlos al componente correspondiente.

Para programar eventos hay que tener en cuenta lo siguiente:

-        Un evento pertenece a un objeto “Oyente” (Listener) o a un objeto “Adaptador” (Adapter)

-        El objeto oyente/adaptador hay que asociarlo al elemento sobre el que sucede el evento.


Por ejemplo: Programar la pulsación de un botón btnSumar.

La pulsación de un botón es un evento actionPerformed como ya se sabe.

El evento actionPerformed pertenece a un objeto llamado ActionListener. El objeto ActionListener es lo que se denomina un oyente.

El objeto ActionListener se asociará al botón btnSumar



Programación de eventos


La programación de eventos es compleja, ya que cada evento pertenece a un oyente/adaptador, y a su vez, hay que asociar cada oyente/adaptador al componente que responde al evento.

Por otro lado, la sintaxis de programación para los eventos es distinta a lo que se ha visto hasta ahora, por lo que puede resultar bastante oscura, aunque por otro lado, siempre sigue el mismo patrón.

Para simplificar el estudio de la programación de eventos, nos limitaremos a los eventos más usados, los cuales pueden clasificarse en los siguientes grupos:

-        Eventos de Acción:

o   actionPerformed
§  Activar un componente (pulsación de botón, enter en un cuadro de texto)

-        Eventos de Teclado:

o   keyPressed
§  Se pulsó una tecla, pero no se soltó.
o   keyReleased
§  Se soltó una tecla.
o   keyTyped
§  Se pulsó y soltó una tecla.

-        Eventos de Ratón:
o   mousePressed
§  Se pulsó un botón del ratón.
o   mouseReleased
§  Se soltó un botón del ratón.
o   mousePressed
§  Se pulsó y soltó un botón del ratón.
o   mouseEntered
§  El ratón entró en la superficie del control.
o   mouseExited
§  El ratón salió de la superficie del control.

-        Eventos de Ventana:

o   windowOpened
§  Se abrió la ventana
o   windowClosing
§  Se cerró la ventana
o   windowActivated
§  Se activó la ventana
o   windowDeactivated
§  Se desactivó la ventana


En esta explicación guiada nos limitaremos a estudiar los eventos de acción.



PROGRAMACIÓN DE EVENTOS DE ACCIÓN:


Un evento de acción hace referencia a la activación de un objeto (un botón, un cuadro de texto, un combo, etc.).

Sólo existe un tipo de evento de acción, llamado actionPerformed.

El evento actionPerformed pertenece a un objeto oyente llamado ActionListener.

Eventos de Acción:


Eventos


Oyente/Adaptador

actionPerformed

Se programan dentro de...
ActionListener

La forma de programar el evento actionPerformed de un componente yyy es la siguiente:


yyy.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent evt) {
          yyyActionPerformed(evt);
     }
});

Para entender la sintaxis de la programación de un evento de acción, supongamos el siguiente ejemplo:


Se quiere programar el evento de un botón llamado btnSumar desde código. He aquí el código para crear el evento:


btnSumar.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent evt) {
          btnSumarActionPerformed(evt);
     }
});


Una explicación del código:



El código anterior permite crear y asignar el evento actionPerformed al botón btnSumar, pero no programa el evento. Para programar el evento es necesario crear el procedimiento cuya llamada se incluye dentro del evento actionPerformed:


public void btnSumarActionPerformed(ActionEvent evt) {
     … aquí se programa el evento actionPerformed del botón btnSumar …
}



A pesar de lo complicado que resulta, hay que tener en cuenta que siempre se programa de la misma forma. Solo hay que cambiar el componente que se quiere programar y asignar un nombre al método donde se programará el evento.

Hay que tener en cuenta que en el código expuesto antes participan nuevas clases como son ActionEvent y ActionListener, y se tendrán que agregar los import correspondientes.


EJERCICIO:

  1. Abra el proyecto Operaciones que se hizo en el ejercicio de la hoja anterior.

  1. En el ejercicio anterior se diseñó desde código la ventana de dicho proyecto. Esta ventana tiene el siguiente aspecto (Se indica también el nombre de los distintos componentes):



  1. El objetivo del ejercicio es programar la pulsación del botón btnSumar para que aparezca un JOptionPane con la suma calculada. Luego haremos lo mismo con el botón btnRestar. Todo esto se hará desde código.



  1. Para recordar, he aquí el código programado hasta ahora. Tenemos una llamada desde el método constructor a un método creacionVentana donde diseñamos cada uno de los elementos de la ventana:

    /**
     * Creates new form VentanaInicial
     */
    public VentanaInicial() {
        initComponents();
        creacionVentana();
    }

    public void creacionVentana() {
        this.setTitle("Programa Operaciones");
        this.setSize(500, 300);
        this.setLocation(100, 100);

        etiNumero1 = new JLabel();
        etiNumero1.setText("Número 1:");
        etiNumero1.setBounds(10, 10, 100, 20);
        this.getContentPane().add(etiNumero1);

        etiNumero2 = new JLabel();
        etiNumero2.setText("Número 2:");
        etiNumero2.setBounds(10, 60, 100, 20);
        this.getContentPane().add(etiNumero2);

        txtNumero1 = new JTextField();
        txtNumero1.setText("0");
        txtNumero1.setBounds(110, 10, 100, 30);
        this.getContentPane().add(txtNumero1);

        txtNumero2 = new JTextField();
        txtNumero2.setText("0");
        txtNumero2.setBounds(110, 60, 100, 30);
        this.getContentPane().add(txtNumero2);

        btnSumar = new JButton();
        btnSumar.setText("Sumar");
        btnSumar.setBounds(10, 120, 100, 30);
        this.getContentPane().add(btnSumar);

        btnRestar = new JButton();
        btnRestar.setText("Restar");
        btnRestar.setBounds(150, 120, 100, 30);
        this.getContentPane().add(btnRestar);
    }


  
  1. Ahora asignaremos un evento actionPerformed al botón btnSumar. Esto lo haremos al final del método creacionVentana, El código que debe añadir para el evento actionPerformed del botón btnSumar es el siguiente:

        btnSumar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                btnSumarActionPerformed(evt);
            }
        });
      

(Recuerda que el código es siempre igual, solo hay que indicar el nombre del botón y el nombre del procedimiento al que se llama).


  1. Será necesario añadir un import para el objeto oyente ActionListener y para la clase ActionEvent.

  1. Ahora que se ha definido un evento actionPerformed para el botón btnSumar, será necesario programarlo. Esto se hace creando el procedimiento al que llama el código del actionPerformed. A este procedimiento le hemos dado de nombre btnSumarActionPerformed.

Así pues, añade el siguiente procedimiento a la clase. (No te vayas a equivocar, el siguiente código está fuera del método creacionVentana).



  1. Es precisamente en este nuevo procedimiento que hemos creado donde se programa el evento actionPerformed del botón btnSumar. Lo que se pretende que haga el programa es que aparezca un JOptionPane con la suma de los números introducidos. Para ello, añade el siguiente código:



  1. Bien, hemos programado la pulsación del botón Sumar. Hemos seguido dos pasos:

    1. Primero hemos creado el evento actionPerformed y se lo hemos asignado al botón. Esto lo hemos hecho dentro del método creacionVentana. Este evento hace una llamada al procedimiento donde se programará la respuesta al evento.

    1. Luego hemos creado ese procedimiento y hemos programado en él el código correspondiente a la pulsación del botón.

Ejecuta el programa y comprueba el funcionamiento del botón Sumar.



  1. Ahora programaremos el botón btnRestar. Primero se tendrá que definir el evento actionPerformed y asignárselo al botón. Esto se hace añadiendo el código de creación del evento al final del método creacionVentana.

        btnRestar.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                btnRestarActionPerformed(evt);
            }
        });


(Observa que es idéntico al código de asignación del evento del botón btnSumar, sólo cambia el nombre del botón y el nombre del procedimiento al que se llama).


  1.  Y ahora, hay que programar el procedimiento al que llama el evento actionPerformed. Es aquí donde se programa la respuesta al evento. En nuestro ejemplo, queremos que al pulsar el botón Restar se resten los números introducidos.

    public void btnRestarActionPerformed(ActionEvent evt) {
        double num1, num2, resta;

        num1 = Double.parseDouble(txtNumero1.getText());
        num2 = Double.parseDouble(txtNumero2.getText());
        resta = num1 - num2;
  JOptionPane.showMessageDialog(null, "La resta es: " + resta);
    }
      

  1. Ejecuta el programa y comprueba el funcionamiento del botón Restar.

  1. Resumiendo una vez más. Para programar un evento sobre un componente, primero hay que enlazar el oyente del evento con el componente, y luego programar el método al que llama el evento. Observa el código que hemos programado:





CONCLUSIONES:

Cada evento pertenece a un objeto oyente, y es el oyente el que se asigna al componente de la ventana que se quiere programar.

El evento actionPerformed pertenece al oyente ActionListener.

Para enlazar el oyente ActionListener a un componente YYY hay que usar el siguiente código:

YYY.addActionListener(new ActionListener() {
     public void actionPerformed(ActionEvent evt) {
          YYYActionPerformed(evt);
     }
});


El enlace de un evento a un componente se hace en el método constructor. Esta asignación hace una llamada a un procedimiento YYYActionPerformed, (donde YYY representa el nombre del componente que se programa). Es en este procedimiento donde realmente se programa el evento.