Anda di halaman 1dari 9

Ejemplos de uso del JFormattedTextField

El JFormattedTextField es un componente java un paso ms evolucionado que un JTextField normalito. El JTextField permite al usuario meter texto. Cuando desde nuestro cdigo le pedimos el contenido, nos devuelve el texto introducido por el usuario como String. Cuando desde cdigo le decimos lo que queremos que muestre, debemos pasarle un String. El JTextField, adems, no hace ningn tipo de comprobacin sobre el texto. El JFormattedTextField da un paso ms all. Aunque el usuario mete un texto, el JFormattedTextField lo convierte a la clase que nosotros queramos (un Integer, Float, Date o incluso una clase nuestra propia). Cuando queramos pasarle algo, le podemos pasar directamente cualquiera de estas clases y l se encarga de la conversin a texto para mostrar.
y y y y

JFormattedTextField para editar Integer JFormattedTextField para editar nuestra propia clase JFormattedTextField con mscara para Float JFormattedTextField con mscara para nuestra propia clase. El InternationalMaskFormatter

JFormattedTextField para editar Integer


Para editar cualquier tipo bsico de java, estilo Integer, Float, Double, Date, etc, basta con llamar al mtodo setValue() del JFormattedTextField pasndole uno de estos tipos de datos, o bien pasrselo en el constructor. Por ejemplo, para Integer, nos bastara con cualquiera de los dos casos siguientes: JFormattedTextField textField1 = new JFormattedTextField (new Integer(3)); // o bien .... JFormattedTextField textField2 = new JFormattedTextField (); textField2.setValue(new Integer(3)); Con esto ya tenemos un editor que nos permite recoger Integer directamente cuando el usuario lo edite

Integer valor = textField1.getValue(); Supongamos que el usuario escribe algo en el JFormattedTextField y luego pincha con el ratn en otros sitio (se dice que el JFormattedTextField pierde el foco), por ejemplo, en un botn de "Aceptar" los cambios introducidos. En el momento que el JFormattedTextField pierde el foco, comprueba el texto escrito por el usuario. Si es correcto, lo guarda de forma que el mtodo getValue() nos devolver el nuevo valor. Si es incorrecto, pondr automticamente el ltimo valor bueno, deshaciendo el cambio hecho por el usuario. Si no te interesa cambiar ese comportamiento, puedes pasar al siguiente punto. Si quieres cambiarlo, sigue leyendo. Este comportamiento puede cambiarse con el mtodo setFocusLostBehavior(), al que podemos pasar varios valores:
y

JFormattedTextField.COMMIT. Si el texto introducido es correcto, se guarda para devolverlo cuando se haga getValue(). Si es incorrecto, no se hace nada, el texto en pantalla queda como esta, o sea, mal. getValue() nos devolver el ltimo valor correcto, independientemente de lo que se muestre en pantalla. JFormattedTextField.REVERT. Cuando hacemos click en otro sitio, el editor vuelve automticamete a su ltimo valor bueno, descartando todas nuestras ediciones, sean correctas o no. Para que esta opcin tenga sentido, debemos llamar desde cdigo al mtodo commitEdit() sin que el JFormattedTextField pierda el foco, por ejemplo, cuando se pulsa <intro> sobre el editor, validando as los cambios realizados. JFormattedTextField.COMMIT_OR_REVERT. Esta es la opcin por defecto y la ms til. Si el texto introducido es incorrecto, se vuelve automticamente al ltimo valor bueno conocido. Si el texto no es vlido, se muestra el ltimo valor bueno conocido.<> JFormattedTextField.PERSIST. Esta opcin no hace nada con el texto introducido, independientemente de que est bien o mal. getValue() siempre devolver el

ltimo valor bueno conocido. Para que el editor recoga el nuevo valor, debemos llamar a commitEdit() previamente. Puedes ver estos cuatro casos funcionando en unos applets de ejemplo. Tambin puedes descargarte los fuentes de los mismos.

JFormattedTextField para editar nuestra propia clase


Podemos usar la forma indicada en el punto anterior con cualquier clase bsica de java (Integer, Float, Date, etc). Si queremos que el JFormattedTextField nos acepte y devuelva una clase nuestra propia, debemos hacer un poco ms de cdigo. Vamos primero a definir nuestra propia clase. Por ejemplo, una clase Mayuscula que representa una cadena de texto siempre en maysculas. Le ponemos un constructor que admita un String para convertirlo a maysculas y un mtodo toString() para obtener la cadena en maysculas. La clase puede ser como esta /**Representa una cadena en maysculas */ class Mayusculas { /** La cadena en maysculas */ private String valor=""; /** Pasa a maysculas la cadena que se le pasa y la guarda */ public Mayusculas(String cadena) { valor = cadena.toUpperCase(); } /** Devuelve la cadena en maysculas */ public String toString() { return valor; } }

Para que el JFormattedTextField nos acepte esto en sus mtodos setValue() y getValue(), tiene que saber la forma de convertir esto a un texto que se muestre en el editor y la forma de convertir el texto recogido del editor y convertirlo a esta clase. Las clases que realizan este tipo de conversiones para el JFormattedTextField heredan de JFormattedTextField.AbstractFormatter, una clase interna del JFormattedTextField. Si queremos usar nuestra clase Mayuscula, debemos hacer una clase hija de JFormattedTextField.AbstractFormatter y definir los dos mtodos abstractos que tiene que son, precisamente, los de convertir de clase a String y de String a clase. /** Clase que sabe convertir Mayuscula a texto para presentar en el editor y de texto recogido del editor obtener una clase Mayscula */ class Formateador extends JFormattedTextField.AbstractFormatter { /** Se le pasa el texto del editor y debe devolver una clase Mayuscula */ public Object stringToValue(String text) throws ParseException { return new Mayusculas(text); } /** Se le pasa una clase Mayuscula o null y devuelve la cadena para poner en el editor */ public String valueToString(Object value) throws ParseException { if (value==null) return (""); return value.toString();

} } Bien, ya tenemos todo lo necesario construido. Ahora solo hay que instanciar el JFormattedTextField pasndole en el constructor nuestra clase Formateador y con setValue() darle un primer valor vlido para evitar problemas. JFormattedTextField textField = new JFormattedTextField(new Formateador()); textField.setValue(new Mayusculas("hola")); El mtodo getValue() nos devolver una clase Mayusculas y a travs de setValue() podemos pasarle una clase Mayusculas sin problemas. Puedes ver un Applet con este editor funcionando y descargarte sus fuentes.

JFormattedTextField con mscara para Float


Existen varios JFormattedTextField.AbstractFormatter adems de los que podamos hacernos nosotros. Uno de los ms conocidos es el MaskFormatter. Este formateador restringe el texto vlido incluso mientras lo estamos tecleando. Al instanciar el MaskFormatter le damos un "patrn" sobre cmo queremos que sea el texto. Una vez configurado todo, el usuario no podr escribir en el FormattedTextField nada que se salga de ese "patrn". Veamos con un ejemplo qu quiero decir. Supongamos que quiero un editor que me permita escribir un nmero con dos cifras enteras y dos decimales. No queremos que el usuario escriba algo que no sea un nmero y no queremos que escriba ni ms ni menos de las cifras de las indicadas. El editor debe admitir y devolvernos con setValue() y getValue() un Float. Para conseguir esto, basta instanciar un MaskFormatter y pasrselo al JFormattedTextField en el constructor. Para evitar problemas, le damos un valor vlido inicial vlido al editor. El new MaskFormatter lanza una excepcin, as que debemos capturarla. try { /* El "patrn" para el editor. Las # representan cifras. En la API puedes ver ms. Ojo con el punto decimal,

segn el idioma puede ser una coma.*/ MaskFormatter mascara = new MaskFormatter("##.##"); // Se construye el JFormattedTextField pasndole la mscara JFormattedTextField textField = new JFormattedTextField(mascara); // Se da un valor inicial vlido para evitar problemas textField.setValue(new Float("12.34")); } catch (...) Ya est listo. Nuestro editor slo admite nmeros de dos cifras enteras y dos decimales y no nos deja escribir otra cosa. Los mtodos getValue() y setValue() devuelven y admiten Floats. Podemos usar el MaskFormatter con cualquier tipo de dato que:
y

Tenga un constructor con String. El MaskFormatter para construir el dato llamar al constructor pasndole el String recogido en el JFormattedTextField. El mtodo toString() devuelva algo que cuadre con el patrn que hemos puesto.

Puedes ver un Applet funcionando con este editor y descargarte sus fuentes.

JFormattedTextField con mscara para nuestra propia clase.


El MaskFormatter nos vale tambin para la clase Date. El problema es que debemos restringirnos a los formatos de texto que entiende Date en su constructor con String, que no son precisamente bonitos ni cmodos para introducir un usuario. Si queremos usar MaskFormatter con un formato distinto para Date o bien usar MaskFormatter con una clase nuestra, debemos hacer algo parecido a lo que hicimos para poder usar nuestras propias clases, pero heredando de MaskFormatter en vez de heredar de JFormattedTextField.AbstractFormatter.

Por ejemplo, supongamos que queremos un editor de Fecha hora en este formato "dd/mm/yy hh:mm:ss" y que no queremos que nos dejen escribir nada incorrecto. Tenemos que hacernos nuestro propio MaskFormatter heredando del original y redefiniendo los mtodos de conversion de Date a String y de String a Date /** Mascara para fecha/hora a nuestro gusto */ class FormatoFecha extends MaskFormatter { /** Se construye con el patrn deseado */ public FormatoFecha() throws ParseException { // Las # son cifras y representa "dd/mm/yy hh:mm:ss" super ("##/##/## ##:##:##"); } /** Una clase adecuada para convertir Date a String y viceversa de forma cmoda. Puedes ver cmo se hace el patrn "dd/MM/yy kk:mm:ss" en la API. El patrn que pongamos aqu debe cuadrar correctamente con la mscara que hemos puesto en el constructor */ private SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yy kk:mm:ss"); /** Convierte el texto del editor en un Date */ public Object stringToValue(String text) throws ParseException { return formato.parseObject(text); } /** Redibe un Date o null y debe convertirlo a texto que cumpla el patrn indicado anteriormente */ public String valueToString(Object value) throws

ParseException { if (value instanceof Date) return formato.format((Date)value); return formato.format(new Date()); } } Ya est todo listo. Simplemente instanciamos el JFormattedTextField pasndole nuestro FormatoFecha y le damos un valor inicial vlido para evitar problemas. Como nuestro constructor lanza una excepcin, hay que meterlo todo en un try-catch. try { JFormattedTextField textField = new JFormattedTextField(new FormatoFecha()); textField.setValue(new Date()); } catch (...) Puedes ver un Applet funcionando con este editor y descargarte sus fuentes.

El InternationalMaskFormatter
Una AbstractFormatter interesante es el InternationalMaskForamatter. Adems de otras muchas cosas, nos permite editar un nmero sin que se salga de un rango determinado. Por ejemplo, un entero entre 10 y 100. Este AbstractFormatter permite escribir cosas incorrectas, pero al final slo admite nmeros entre el rango indicado. Su uso es sencillo, basta algo como esto InternationalFormatter formato = new InternationalFormatter(); formato.setMaximum(new Integer(100)); formato.setMinimum(new Integer(10)); JFormattedTextField textField = new

JFormattedTextField(formato); textField.setValue(new Integer(90)); Puedes ver un Applet funcionando con este editor y descargarte sus fuentes.

Anda mungkin juga menyukai