lunes, 24 de marzo de 2014

Ejemplo Eventos del Teclado en Java

En la entrada anterior tocamos el tema de los eventos del Mouse, en esta ocasión continuaremos trabajando con Eventos pero ahora del Teclado...

Vamos a hacer un ejemplo muy simple teniendo en cuenta que ya sabemos lo que es un evento (si no lo sabes, revisa el articulo anterior).....
en el ejemplo escribiremos en un área de texto y mediante eventos del teclado identificaremos y contaremos la cantidad de vocales escritas...

Este ejemplo es muy similar al anterior ya que también es necesario implementar una interface, en este caso la elegida es la KeyListener, que nos provee los métodos para controlar los eventos del teclado...

Al implementar la interface debemos implementar también los métodos que la componen, veamos cuales son y su funcionamiento básico:

keyPressed(KeyEvent e): Se ejecuta cuando el usuario presiona una tecla.
keyReleased(KeyEvent e): Se ejecuta cuando el usuario libera una tecla
keyTyped(KeyEvent e): Se ejecuta cuando el usuario presiona una tecla, pero solo cuando la tecla corresponde a caractéres, teclas especiales como F1, F2 entre otras no son identificadas.

Por lo regular el uso de estos métodos es muy especifico todo depende de lo que necesitemos ya que el evento de presionar y soltar pasa muy rápido y casi nunca nos damos cuenta cual evento se ejecutó, estos métodos son usados básicamente cuando queremos controlar al detalle lo que queremos que suceda si se hace una u otra acción...... mas abajo veremos esto en el ejemplo.....bueno ahora si a lo que vinimos.....

El Ejemplo.
Ventana Principal
Como se mencionó para este ejemplo vamos a trabajar con 2 JTextArea, una donde introduciremos el texto y otra donde veremos las vocales presionadas, así mismo podremos saber la cantidad de vocales que contiene el texto escrito.........adicionalmente agregaremos un evento a la tecla Esc para indicarle al sistema que el usuario quiere cerrar la aplicación....

Clase Aplicacion.

Esta clase es muy conocida pero nunca sobra ponerla, simplemente desde aquí por medio del método main() hacemos el llamado a la ventana principal...
public class Aplicacion {
  public static void main(String args[]) {
      Ventana ventana;
      ventana = new Ventana();
      ventana.setVisible(true);
   }
}

Clase Ventana.

Esta clase corresponde a la interfaz gráfica de nuestro sistema, podemos ver que implementa la interface por medio del implements KeyListener,  sin esto no podríamos capturar los eventos......veamos
class Ventana extends JFrame implements KeyListener {
  JLabel labelTitulo;
  JLabel labelAreaEntrada;
  JLabel labelAreaSalida;
  JLabel labelSalida;
  JLabel labelContadorVocales;
  JTextArea areaEntradaDeTexto;
  JScrollPane scrollPaneAreaEntrada;
  JTextArea areaSalidaDeTexto;
  JScrollPane scrollPaneAreaSalida;

  int cantidadVocales=0;
  String vocales="";
  
public Ventana() {
     setLayout(null);
     iniciaComponentes();
     //Asigna un titulo a la barra de titulo
     setTitle("CoDejaVu : Ventana Eventos del Teclado");
     //tamaño de la ventana
     setSize(550,350);
     //pone la ventana en el Centro de la pantalla
     setLocationRelativeTo(null);
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   }

private void iniciaComponentes() {
  labelTitulo= new JLabel();
  labelTitulo.setFont(new java.awt.Font("Comic Sans MS", 0, 28));
  labelTitulo.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
  labelTitulo.setText("Eventos del Teclado");
  labelTitulo.setBorder(javax.swing.BorderFactory.
 createBevelBorder(javax.swing.border.BevelBorder.RAISED));
  labelTitulo.setBounds(110, 20, 300, 40);
 
  labelAreaEntrada= new JLabel();
  labelAreaEntrada.setBounds(10, 70, 180, 40);
  labelAreaEntrada.setText("Area Entrada de Texto");
  
  areaEntradaDeTexto = new JTextArea();
  areaEntradaDeTexto.setLineWrap(true);
  areaEntradaDeTexto.addKeyListener(this);
  
  scrollPaneAreaEntrada = new JScrollPane();
  scrollPaneAreaEntrada.setBounds(10, 100, 513, 70);
  scrollPaneAreaEntrada.setViewportView(areaEntradaDeTexto);
        
  labelAreaSalida= new JLabel();
  labelAreaSalida.setBounds(10, 170, 180, 40);
  labelAreaSalida.setText("Area Salida de Texto");
  
  areaSalidaDeTexto = new JTextArea();
  areaSalidaDeTexto.setLineWrap(true);
  areaSalidaDeTexto.addKeyListener(this);
  
  scrollPaneAreaSalida = new JScrollPane();
  scrollPaneAreaSalida.setBounds(10, 200, 513, 70);
  scrollPaneAreaSalida.setViewportView(areaSalidaDeTexto);
 
  labelContadorVocales = new JLabel();
  labelContadorVocales.setBounds(380, 280, 190, 20);
  
  labelSalida = new JLabel();
  labelSalida.setText("Para salir presione la tecla Escape");
  labelSalida.setBounds(10, 280, 210, 20);
  
  add(labelTitulo);
  add(labelSalida);
  add(labelContadorVocales);
  add(labelAreaEntrada);
  add(labelAreaSalida);
  add(scrollPaneAreaEntrada);
  add(scrollPaneAreaSalida);
  
}

/**Este metodo se ejecuta cuando se presiona una tecla*/
 @Override
public void keyPressed(KeyEvent e) {
  
  if (e.getSource()==areaEntradaDeTexto)
   {
 if (e.VK_A==e.getKeyCode())
         {
    vocales+="a ";
    cantidadVocales++;
  }
 if (e.VK_E==e.getKeyCode())
  {
    vocales+="e "; 
    cantidadVocales++;
  }
 if (e.VK_I==e.getKeyCode())
  {
    vocales+="i ";
    cantidadVocales++;
  }
 if (e.VK_O==e.getKeyCode())
  {
    vocales+="o "; 
    cantidadVocales++;
  }
 if (e.VK_U==e.getKeyCode())
  {
   vocales+="u ";
   cantidadVocales++;
  }
  } 
  areaSalidaDeTexto.setText(vocales);
  labelContadorVocales.setText("Numero Vocales: "+cantidadVocales);
}

/**Este metodo se ejecuta cuando se suelta una tecla*/
@Override
public void keyReleased(KeyEvent e) {
  System.out.println("Soltó la tecla:  "+e.getKeyText(e.getKeyCode()));
   if (e.getSource()==areaEntradaDeTexto)
     {
 if (e.VK_ESCAPE==e.getKeyCode())
        {
 int respuesta = JOptionPane.showConfirmDialog(this,
  "Esta seguro que desea salir?", "Confirmación",
  JOptionPane.YES_NO_OPTION);
 if (respuesta == JOptionPane.YES_NO_OPTION)
 {
  System.exit(0);
 }
      }
   } 
}

/**Este metodo funcionará solo cuando se presionan caracteres, 
 *si se presionan teclas como F1, F2, inicio etc no ejecutará 
 *ningun evento*/
  @Override
  public void keyTyped(KeyEvent e) {
  }
}

Es importante recalcar que también es de suma importancia indicarle al sistema cual es el componente que va a escuchar los eventos del teclado, en este caso vamos a escribir en un área de texto, si no se hace aunque tengamos la interface, no se reconocerán los eventos.... para eso se debe indicar agregando el addKeyListener(this) así:

areaSalidaDeTexto.addKeyListener(this);

Bueno teniendo esto mas claro ahora vamos a centrarnos en los métodos keyPressed(KeyEvent e) y keyReleased(KeyEvent e)...

En keyPressed validamos cuando se presionan las vocales para ir asignando los valores correspondientes al área de texto y a la variable que las cuenta......

En KeyReleased lo que hacemos es validar el evento cuando se presiona la tecla Escape para salir del sistema, al presionar la tecla se carga el mensaje....

Adicional a esto también imprimimos en consola cual es la tecla presionada, de esta manera nos damos cuenta cada espacio, enter, delete y cualquier tecla que utilicemos....


Viendo el código podríamos preguntarnos el porque hicimos el evento de salir en el KeyReleased, si esto también lo podríamos haber hecho sin problemas en el
KeyPresed.......o no?

Simplemente lo hicimos ahí para ver el ejemplo del que hablamos al principio..... cual método usar depende básicamente de lo que necesitemos.... los eventos suceden muy rápido pero en este caso, como queremos imprimir que tecla se liberó.... si hubiéramos puesto la validación de la tecla Escape al presionar el botón, entonces se cargaría el dialogo de confirmación y si es afirmativo se cerraría la aplicación, sin darnos tiempo de ver en consola que la tecla Escape fue liberada.... mientras que en el KeyReleased si alcanzamos a ver en consola que el escape se presionó....... en este caso no es algo tan grave, pero supongamos que eso sea algo muy importante y que no solo es mostrarse en consola sino almacenarse esa información en un archivo de texto siendo necesaria toda la información posible......

También es importante saber que aunque no utilicemos el método keyTyped, se debe dejar enunciado, ya que es un principio del trabajo con interfaces y debemos implementar todos los métodos de esta.... si no sabes a que me refiero te invito a leer esta entrada sobre interfaces...

Y listo aquí termina nuestro ejemplo, espero que les pueda servir y sea de fácil entendimiento...


También te podría Interesar.


¿Hay algo que quieras anexar o comentar sobre esta entrada?  no dudes en hacerlo.....y si te gustó...... te invito a compartir
 y Suscribirte ingresando al botón "Participar en este sitio" para darte cuenta de mas entradas como esta ;)

32 comentarios:

  1. muy bien hermano ahora me kedo claro como se hace el atajo de teclados

    ResponderEliminar
    Respuestas
    1. Ing, Me alegra que le sirviera ;)

      Eliminar
    2. Este comentario ha sido eliminado por el autor.

      Eliminar
    3. por favor necesito programa que al precionar la tecla f1 me imprima una ventana nueva e intentado pero me rindo siempre me sale un erro cuando declaro la nueva ventana

      Eliminar
    4. porfavor programa que al precionar la tecla f1 me imprima una ventana nueva

      Eliminar
    5. Aun lo necesitas puedo ayudarte

      Eliminar
    6. disque Ing. y apenas entendio los eventos

      Eliminar
    7. disque Ing. y no sabe escribir ni el "quedó" (kedo, que es eso?) :S

      Eliminar
  2. es de mucha ayuda con estos ejemplos podre hacer mas factible mi sistema

    ResponderEliminar
  3. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  4. buenas.. muy bueno el aporte.. resolvio un proble que tenia en el cod.. estoy programando en MVC..
    e hice las validaciones en la Vista y me funcionan perfecto..
    pero cuando las coloco en el Controlador no me sirven..
    tengo un campo JTextField que es usado para la insercion de una Cédula.. el campo solo debe permitir numeros.. pero no se xq en el Controlador no me sirve..

    public void keyPressed(KeyEvent e) {


    if (e.getSource()==vp.cedula)
    {
    char c = e.getKeyChar();
    if((c<'0' || c>'9') && (c!=(char)KeyEvent.VK_BACK_SPACE))
    {
    e.consume();
    Toolkit.getDefaultToolkit().beep();
    }else{
    }
    }
    }

    este codigo en la vista me funciona sin proble..
    de antemano gracias.. excelente aporte.!

    ResponderEliminar
    Respuestas
    1. el sistema ejecuta el pitido del "Toolkit.getDefaultToolkit().beep();".. pero no consume el evento para bloquear la insercion de caracteres q no estan permitidos.! :/

      Eliminar
    2. solucionado.!

      la solucion fue colocarlo en KeyTyped.. >.<

      gracias de igual forma :3

      Eliminar
  5. Muy bueno la publicación gracias, pero quisiera saber si se puede hacer lo mismo pero fuera de jframe, porque estoy haciendo un sistema y se quiere que se detecte cuando hay inactividad en la computadora durante un minuto.

    ResponderEliminar
  6. Buenas amigo me podría decir cual es el codigo cuando se presiona f5 por favor desde ya gracias y. Saludos

    ResponderEliminar
  7. Amigo no puedes subir el proyecto? Gracias

    ResponderEliminar
  8. Necesito mostrar un mensaje cuando se presiona la tecla print screen que corresponde a captura de pantalla

    ResponderEliminar
  9. Alguien? quiero tratar de hacer que al escribir el un jtextfield, en otro haga una funcion segun escriba en el primero; es decir, quiero que en el primero reciba el dato int, lo multiplique con un valor especifico ya reconocido y lo lea al instante en el segundo jtextfield :( T.T soy nuevo hep mi

    ResponderEliminar
  10. Es muy útil y lleva mucho tiempo usar aplicaciones para eventos.
    App para Eventos

    ResponderEliminar
  11. Gracias por compartir información sobre aplicaciones para eventos.
    Aplicación APP Móvil para Organizar Eeventos

    ResponderEliminar
  12. muy buena la información gracias :3

    ResponderEliminar
  13. La pregunta que tengo es con algo que se presenta casi en el comienzo del código, cuando se empieza a crear la clase Ventana, que seguido línea abajo creas algo así como jLabel labelTitulo; y siguiente linea abajo jLabel labelAreaEntrada; y así sucesivamente hay como 7 líneas así parecidas, la inquietud que tengo, es porque se hace esta parte así? Es necesario hacer esta parte así? No bastaría solo con crear el objeto y ya?

    ResponderEliminar

Eres libre de realizar cualquier comentario, desde que pueda ayudar con gusto lo atenderé, y si es un critica, bienvenida sea!!!