Sucesos (events) |
Verificación de los datos mientras se introducen
Verificación después de introducir los datos
La mayoría de los applets disponen de controles de edición en los que se introducen datos para su procesamiento por el programa. La verificación de los datos que se introducen en los controles de edición tiene gran importancia para el correcto funcionamiento del programa.
La verificación del dato, se puede realizar mientras se teclean los caracteres o bien después de haber introducido dicho dato en el control de edición. El primer caso, se emplea para eliminar los caracteres no deseados que tecleamos sin darnos cuenta, por ejemplo letras cuando se requieren caracteres numéricos o viceversa. El segundo caso, se emplea por ejemplo, para verificar que la cantidad introducida está dentro de un intervalo apropiado.
Se crea el control de edición llamanado a uno de sus constructores
TextField textEntero = new TextField();
Se establece el tamaño del control mediante setColums
textEntero.setColumns(4);
Se puede habilitar o inhabilitar el control de edición, es decir, puede hacerse de lectura/escritura o de sólo lectura.
textEntero.setEditable(false);
Para poner texto en el control de edición, se llama a setText.
textEntero.setText("3");
Para obtener el texto del control de edición, se emplea getText.
String texto=textEntero.getText();
edicion1: EdicionApplet1.java
Filtrar los caracteres que se introducen en el control de modo que solamente se muestren caracteres no numéricos.
Crear un applet y situar sobre el applet en el modo diseño (pestaña Design) un control etiqueta (Label) y un control de edición (TextField).
Cambiar sus propiedades en sus respectivas hojas de propiedades
Establecer FlowLayout como gestor de diseño del applet
Para gestionar los sucesos procedentes del teclado que se producen en un componente, se han de seguir los siguientes pasos.
public interface KeyListener extends EventListener { public void keyTyped(KeyEvent e); public void keyPressed(KeyEvent e); public void keyReleased(KeyEvent e); }
En vez de implementar el interface KeyListener, tenemos la opción de crear una clase que derive de la clase KeyAdapter (véase Listeners y adapters) y redefinir algunas de sus funciones miembro por ejemplo, keyPressed.
class ValidaCaracter extends KeyAdapter{ public void keyPressed(KeyEvent ev){ int codigo=ev.getKeyCode(); if(codigo>=KeyEvent.VK_0 && codigo<=KeyEvent.VK_9){ ev.consume(); } } }
El objeto ev de la clase KeyEvent nos suministra código de la tecla que se ha pulsado que se extrae mediante su función miembro getKeyCode o el carácter tecleado mediante getKeyChar. Si dicho código corresponde a una tecla numérica, el suceso se consume, conlcuye su procesamiento, y por tanto, no se muestra en el control de edición.
int codigo=ev.getKeyCode(); if(codigo>=KeyEvent.VK_0 && codigo<=KeyEvent.VK_9){ ev.consume(); }
Otra forma equivalente sería la siguiente
char tecla=ev.getKeyChar(); if(tecla>='0' && tecla<='9'){ ev.consume(); }
Asociamos mediante addKeyListener, el control de edición textIntro en el que ocurren los sucesos relacionados con el teclado, con un objeto de la clase ValidaCaracter que maneja dichos sucesos.
ValidaCaracter valChar=new ValidaCaracter(); textIntro.addKeyListener(valChar);
o bien, en una sóla línea
textIntro.addKeyListener(new ValidaCaracter());
De un modo análogo, se podría definir una clase que filtrase los caracteres numéricos.
El código completo de este ejemplo, es el siguiente
package edicion1; import java.awt.*; import java.awt.event.*; import java.applet.*; public class EdicionApplet1 extends Applet { TextField textIntro = new TextField(); Label label1 = new Label(); FlowLayout flowLayout1 = new FlowLayout(); public void init() { textIntro.setColumns(10); label1.setText("Introducir carcateres NO numéricos"); this.setLayout(flowLayout1); this.add(label1, null); this.add(textIntro, null); ValidaCaracter valChar=new ValidaCaracter(); textIntro.addKeyListener(valChar); } } class ValidaCaracter extends KeyAdapter{ public void keyPressed(KeyEvent ev){ int codigo=ev.getKeyCode(); if(codigo>=KeyEvent.VK_0 && codigo<=KeyEvent.VK_9){ ev.consume(); } } } |
edicion2: EdicionApplet2.java
El propósito del programa es verificar la información que ha introducido el usuario en los controles de edición. En el primer control de edición se espera que introduzca un número entero, y en el segundo un número decimal. Si se introducen caracteres no numéricos, o una coma como separador de la parte entera y decimal el control de edición recupera el foco, para que el usuario corrija los errores.
Nota: Es posible que el applet no funcione en el navegador Internet Explorer 4.0 de Microsoft como se describe, pero funciona correctamente en el AppletViewer del IDE JBuilder 2.0.
Crear un applet, en el modo diseño (pestaña Design), situar tres paneles, uno en la parte superior, otro en el centro y otro en la parte inferior, tal como se indica en la figura.
Cambiar las propiedades de cada uno de los controles en sus respectivas hojas de propiedades.
Establecer FlowLayout como gestor de diseño de cada uno de los paneles
Establecer BorderLayout como gestor de diseño del applet, de modo que el panel superior quede al norte (NORTH), el central en el centro (CENTER) y el inferior en el sur (SOUTH).
Nota acerca de los paneles:
Cuando se coloca un panel AWT sobre el applet en el modo diseño, se hace invisible para el programador. Este inconveniente se puede resolver de dos formas distintas:
import borland.jbcl.control.*; import borland.jbcl.layout.*;
Cuando un control de edición tiene el foco podemos introducir caracteres en dicho control, cuando pulsamos la tecla del tabulador, el foco pasa a otro control, y así sucesivamente.
Para gestionar los sucesos asociados al cambio de foco, se han de seguir los siguientes pasos.
public interface FocusListener extends EventListener { public void focusGained(FocusEvent e); public void focusLost(FocusEvent e); }
En vez de implemantar el interface FocusListener, tenemos la opción de crear una clase que derive de la clase FocusAdapter (véase Listeners y adapters) y redefinir algunas de sus funciones miembro por ejemplo focusLost.
Podemos verificar el dato introducido en un control de edición cuando dicho control pierde el foco.Vamos a ver dos ejemplos: verificar que se introduce un número entero y verificar que se introduce un número decimal.
En primer lugar, creamos una clase que deriva de FocusAdapter, (véase Listeners y adapters) y redefinimos la función miembro focusLost en la que estamos interesados.
class ValidaInt extends FocusAdapter{ public void focusLost(FocusEvent ev){ TextField tEntrada=(TextField)(ev.getSource()); try{ Integer.parseInt(tEntrada.getText().trim()); }catch(NumberFormatException e){ tEntrada.requestFocus(); tEntrada.selectAll(); } } }
El objeto ev de la clase FocusEvent guarda toda la información relativa al suceso, y en particular, la fuente o el control que lo ha generado, dicha información se extrae mediante la función getSource.
Una vez que se ha obtenido el control de edición tEntrada que ha generado el suceso, se obtiene el texto, un objeto de la clase String, que se ha introducido en dicho control mediante la función getText.
Posteriormente, se eliminan los espacios en blanco al principio y al final mediante la función trim, y se convierte el string en un número entero mediante la función parseInt.
Si el proceso de conversión falla, por que se han introducido caracteres que no son números, se produce un excepción del tipo NumberFormatException. En este caso, el control de edición vuelve a tomar el foco requestFocus, y se selecciona todos los caracteres introducidos para que puedan ser borrados de una sola vez pulsando la tecla RETROCESO.
tEntrada.requestFocus(); tEntrada.selectAll();
Asociamos, mediante addFocusListener, el control de edición textEntero en el que ocurren los sucesos relacionados con el teclado con un objeto de la clase ValidaInt que registra dichos sucesos.
ValidaInt valInt=new ValidaInt(); textEntero.addFocusListener(valInt);
o bien, en una sóla línea de código
textEntero.addFocusListener(new ValidaInt());
Lo mismo que hemos hecho para un número entero se puede repetir para un número real. Esto es importante, ya que tenemos la costumbre de poner una coma como carácter separador de la parte entera y de la parte decimal, lo que no es admitido por el programa. Por tanto, para su buen comportamiento debemos de notificar esta circustancia al usuario.
class ValidaDouble extends FocusAdapter{ public void focusLost(FocusEvent ev){ TextField tEntrada=(TextField)(ev.getSource()); try{ Double.valueOf(tEntrada.getText()).doubleValue(); }catch(NumberFormatException e){ tEntrada.requestFocus(); tEntrada.selectAll(); } } }
Asociamos, mediante addFocusListener, el control de edición textDecimal en el que ocurren los sucesos relacionados con el teclado con un objeto de la clase ValidaDecimal que registra dichos sucesos.
ValidaDouble valDouble=new ValidaDouble(); textDecimal.addFocusListener(valDouble);
o bien, en una sóla línea de código
textDecimal.addFocusListener(new ValidaDouble());
El código fuente completo de este ejemplo, es el siguiente
package edicion2; import java.awt.*; import java.awt.event.*; import java.applet.*; public class EdicionApplet2 extends Applet { TextField textEntero = new TextField(); TextField textDecimal = new TextField(); Button btnAceptar = new Button(); Panel bevelPanel1 = new Panel(); Panel bevelPanel2 = new Panel(); Panel bevelPanel3 = new Panel(); Label label1 = new Label(); Label label2 = new Label(); FlowLayout flowLayout1 = new FlowLayout(); FlowLayout flowLayout2 = new FlowLayout(); FlowLayout flowLayout3 = new FlowLayout(); BorderLayout borderLayout1 = new BorderLayout(); public void init() { this.setLayout(borderLayout1); btnAceptar.setLabel("Aceptar"); bevelPanel3.setLayout(flowLayout3); bevelPanel2.setLayout(flowLayout2); bevelPanel1.setLayout(flowLayout1); //número entero textEntero.setText("3"); textEntero.setColumns(4); label1.setText("Introduce un número entero"); ValidaInt valInt=new ValidaInt(); textEntero.addFocusListener(valInt); //número decimal textDecimal.setText("1.3"); textDecimal.setColumns(4); label2.setText("Introduce un número decimal"); ValidaDouble valDouble=new ValidaDouble(); textDecimal.addFocusListener(valDouble); this.add(bevelPanel1, BorderLayout.NORTH); bevelPanel1.add(label1, null); bevelPanel1.add(textEntero, null); this.add(bevelPanel2, BorderLayout.CENTER); bevelPanel2.add(label2, null); bevelPanel2.add(textDecimal, null); this.add(bevelPanel3, BorderLayout.SOUTH); bevelPanel3.add(btnAceptar, null); } } class ValidaDouble extends FocusAdapter{ public void focusLost(FocusEvent ev){ TextField tEntrada=(TextField)(ev.getSource()); try{ Double.valueOf(tEntrada.getText()).doubleValue(); }catch(NumberFormatException e){ tEntrada.requestFocus(); tEntrada.selectAll(); } } } class ValidaInt extends FocusAdapter{ public void focusLost(FocusEvent ev){ TextField tEntrada=(TextField)(ev.getSource()); try{ Integer.parseInt(tEntrada.getText().trim()); }catch(NumberFormatException e){ tEntrada.requestFocus(); tEntrada.selectAll(); } } } |