Está en la página 1de 11

Cmo usar Text Field

Los campos de texto muestran una sla lnea de texto selecionable y


opcionalmente editable. Generalmente se usa la clase JTextField para
proporcionar campos de texto. Si necesitamos proporcionar un campo de
password -- un campo de texto editable que no muestre los caracteres
tecleados por el usuario -- se utiliza la clase JPasswordField. Esta pgina
describe ambas clases.
Si queremos que un campo de texto que tambin proporcione un men de
strings de las que eligir, podemos considerar la utilizacin de un combo
box editable. Si necesitamos obtener ms de una lnea de entrada del
usuario, deberamos usar una las clases que implementan reas de texto de
propsito general.
Este applet es una versin Swing del programa AWT descrito en Cmo usar
Campos y reas de Texto.
El Applet muestra un campo de texto bsico y un rea de texto. El campo
de texto es editable y el rea no. Cuando el usuario pulsa el botn Return en
el campo de texto, dispara un evento action. El applet reacciona al evento
copiando el contenido del campo de texto en el rea de texto y luego
seleccionando todo el texto del campo de texto.
Podemos encontrar el cdigo fuente del programa en TextDemo.java. El
correspondiente fichero HTML, TextDemo.html, contiene una
etiqueta <APPLET> para ejecutar el applet. Aqu est el cdigo
de TextDemo que crea el campo de text en el applet:
textField = new JTextField(20);
...
getContentPane().add(textField);
...
textField.addActionListener(this);
El constructor de JTextField toma un prametro entero indicando el
nmero de columnas del campo de texto. Las siguientes lneas de cdigo
aaden el campo de texto al panel de contenido del applet, y registra el
applet como oyente de actin del campo de texto. Aqu est el
mtodo actionPerformed que maneja los eventos action del campo de texto:
public void actionPerformed(ActionEvent evt) {
String text = textField.getText();
textArea.append(text + newline);
textField.selectAll();
}
Este ejemplo ilustra el uso de un campo de texto bsico y autocontenido
para introducir datos textuales y realizar alguna tarea cuando el campo de
texto dispara un evento action. Esto es suficiente para muchos programas.
Otros, sin embargo, necesitan un comportamiento ms avanzado. Como una
subclase de JTextComponent, JTextField puede ser configurada y
personalizada. Una personalizacin comn es proporcionar un campo de
texto cuyos contenidos sean validados. Este tpico y otros ms se cubren en
las siguientes secciones:
Crear un Campo de Texto Validado
Usar un Oyente de 'Document' en un Campo de Texto
Distribuir las parejas etiqueta/campo de texto
Proporcionar un Password Field
El API Text Field
Ejemplos que usan Text Fields
Crear un Campo de Texto Validado
Muchos programas requieren que los usuarios introduzcan datos textuales
de un cierto tipo o formato. Por ejemplo, un programa podra proporcionar
un campo de texto para introducir una fecha, un nmero decimal, o un
nmero de telfono. El contenido de dichos campos debe ser validado antes
de usarlos para cualquier propsito. Un campo de texto puede ser validado-
action(accin) o validadokeystroke(pulsacin).
Los datos en un campo validado-action se chequean cada vez que se dispara
un evento actin (cada vez que el usuario pulsa la tecla Return). Un campo
validado-action podra, en un momento dado, contener datos no vlidos. Si
embargo, los datos son validados antes de utilizarlos para otra cosa. Para
crear un campo validado-action, proporcionamos un oyente de 'action' para
nuestro campo e implementamos su mtodo actionPerformed de esta forma:
Usar getText para obtener el contenido del campo de texto.
Evaluar el valor devuelto por getText.
Si el valor es vlido, hacer las tareas o clculos requeridos. Si
el valor no es vlido, informar del error y volver sin realizar la
tarea o clculo.
En un campo validado-keystroke los datos se chequean cada vez que
cambian. Una campo validado-keystroke nunca puede contener datos no
vlidos porque cada pulsacin hace que el dato no vlido sea rechazado. Para
crear un campo de texto validado-keystroke necesitamos proporcionar un
documento personalizado a nuestro campo de texto. Si no ests
familiarizado con los documentos, puedes ver la seccin Trabajar con el
Documento de un Componente de Texto.

Aviso: No se usa un oyente de 'Document' para validacin de pulsaciones. El
momento en que el documento nitifica un cambio es demasiado tarde, el
cambio ya ha tenido lugar. Puedes leer los dos ltimos parrfos de la
seccin Escuchar los Cambios en un Documento para ms informacin.

La aplicacin mostrada en la siguiente figura tiene cuatro campos de texto
validados-keystroke. El usuario introduce la informacin en los tres
primeros campos. Cada vez que el usuario teclea un caracter, el programa
valida la entrada y actualiza el resultado en el cuarto campo de texto.


Intenta esto:
1. Compila y ejecuta la aplicacin. El fichero fuente
es TextFieldDemo.java. Tambin
necesitars WholeNumberField.java, DecimalField.java,
y FormattedDocument.java.
2. Introduce informacin en los campos de texto y mira el
resultado.
Si intentas introducir datos no vlidos, el programa hace
sonar un beep.
3. Intenta teclear algo en el cuarto campo de texto.
No puedes porque no es editable. Sin embargo, se puede
seleccionar el texto.
4. Redimensiona la ventana.
Observa que las etiquetas y los campos de texto
permanecen alienados. En Distribuir las Parejas
Etiqueta/Campo de Texto hay ms informacin sobre
esta caracterstica del programa.

El campo Years es un ejemplar de WholeNumberField.java, que es una
subclase de JTextField. Sobreescribiendo el
mtodo createDefaultModel, WholeNumberField establece una subclase
de Documentpersonalizada - un ejemplar de WholeNumberDocument --
como el documento de cada WholeNumberField creado:
protected Document createDefaultModel() {
return new WholeNumberDocument();
}
Aqu est la implementacin de WholeNumberDocument:
protected class WholeNumberDocument extends PlainDocument {

public void insertString(int offs, String str, AttributeSet a)
throws BadLocationException {

char[] source = str.toCharArray();
char[] result = new char[source.length];
int j = 0;

for (int i = 0; i < result.length; i++) {
if (Character.isDigit(source[i]))
result[j++] = source[i];
else {
toolkit.beep();
System.err.println("insertString: " + source[i]);
}
}
super.insertString(offs, new String(result, 0, j), a);
}
}
Esta clase sobreescribe el mtodo insertString que es llamado cada vez que
se va a insertar un string o un caracter en el documento. La implementacin
que hace WholeNumberDocument de insertStringevalua cada caracter a
insertar en el campo de texto. Si el caracter es un dgito, el documento
permite que sea insertado. De otro modo, el mtodo hace un beep e imprime
un mensaje de error. Por lo tantoWholeNumberDocument permite los
nmeros en el rango 0, 1, 2, ...
Un interesante detalle de implementacin es que nuestro documento
personalizado no tiene que sobreescribir el mtodo remove. Este mtodo es
llamado cada vez que se elimina un caracter o un grupo de caracteres del
campo de texto. Como eliminar un dgito de un entero no puede producir un
resultado no vlido, esta clase no le presta atencin a las eliminaciones.
Los otros dos campos de entrada del ejemplo, as como el campo no
editable Monthly Payment, son todos ejemplares de DecimalField.java, una
subclase personalizada de JTextField. DecimalField usa un documento
personalizado FormattedDocument, que slo permite la introduccin de
datos en un formato particular.
FormattedDocument no tiene conocimineto del formato real de su
contenido. En su lugar, FormattedDocument relega el formato en una
subclase de Format, para aceptar o rechazar un cambio propuesto. El campo
de texto que usa el FormattedDocument decide que formato utilizar.
Los campos de texto Loan Amount y Monthly Payment usan un
objeto NumberFormat creado de esta forma:
moneyFormat = NumberFormat.getCurrencyInstance(Locale.US);
((DecimalFormat)moneyFormat).setPositiveSuffix(" ");
El siguiente cdigo crea el formato del campo de texto APR:
percentFormat = NumberFormat.getPercentInstance(Locale.US);
percentFormat.setMinimumFractionDigits(3);
Como muestra el cdigo, la misma clase (NumberFormat) puede soportar un
formato de moneda y otro de porcentaje. Adems, Format y sus subclases
son sensibles a la localidad, por eso el campo decimal puede crearse para
soportar formatos de otros paises o regiones. Puedes ver la
pgina Formatear nmeros en la seccin de internacionalizacin para
informacin ms detalladas sobre los formatos.
Aqu est la implementacin que hace FormattedDocument de insertString:
public void insertString(int offs, String str, AttributeSet
a)
throws BadLocationException {

String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(offs,
currentText.length());
String proposedResult = beforeOffset + str +
afterOffset;

try {
format.parseObject(proposedResult);
super.insertString(offs, str, a);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("insertString: could not parse:
" + proposedResult);
}
}
El mtodo usa el formateador para analizar el resultado de la insercin
propuesta. Si el resultado se formatea correctamente, el mtodo llama al
mtodo insert de su superclase para realizar la insercin. Si el resultado no
se formatea correctamente, el ordenador hace un beep.
Adems de sobreescribir el
mtodo insertString, FormattedDocument tambin sobreescribe el
mtodo remove. Recuerda que este mtodo es llamado cada vez que se
elimina del documento un caracter o un grupo de caracteres.
public void remove(int offs, int len) throws
BadLocationException {
String currentText = getText(0, getLength());
String beforeOffset = currentText.substring(0, offs);
String afterOffset = currentText.substring(len + offs,
currentText.length());
String proposedResult = beforeOffset + afterOffset;

try {
if (proposedResult.length() != 0)
format.parseObject(proposedResult);
super.remove(offs, len);
} catch (ParseException e) {
Toolkit.getDefaultToolkit().beep();
System.err.println("remove: could not parse: " +
proposedResult);
}
}
La implementacin del mtodo remove es similar al mtodo insertString. El
formateador analiza el resultado del cambio propuesto y realiza la
eliminacin o no, dependiendo de si el resultado es vlido.
Usar un Oyente de 'Document' sobre un campo de texto
Por eso, si no podemos usar un oyente de 'document' para validacin de
campos, que podemos utilizar? Podemos usar un oyente de, pero no
interferir con, los cambios del contenido del documento. El calculador de
crditos usa el siguiente oyente de 'document' para actualizar el pago
mensual despus de cada cambio:
class MyDocumentListener implements DocumentListener {
public void insertUpdate(DocumentEvent e) {
update(e);
}
public void removeUpdate(DocumentEvent e) {
update(e);
}
public void changedUpdate(DocumentEvent e) {
// we won't ever get this with a PlainDocument
}
private void update(DocumentEvent e) {
Document whatsup = e.getDocument();
if (whatsup.getProperty("name").equals("amount"))
amount = amountField.getValue();
else if (whatsup.getProperty("name").equals("rate"))
rate = rateField.getValue();
else if (whatsup.getProperty("name").equals("numPeriods"))
numPeriods = numPeriodsField.getValue();
payment = computePayment(amount, rate, numPeriods);
paymentField.setValue(payment);
}
}
Este es un uso apropiado de un oyente de 'document'. Para ms informaicn
sobre los oyentes de 'document' puedes ver la pgina Cmo escribir un
Oyente de 'Document'.
Distribuir las parejas Etiqueta/Campo de Texto
Las filas de parejas etiqueta/campo de texto como las encontradas en el
calculador de crditos son bastante comunes en paneles de preferencias y
paneles de formularios. Aqu est el cdigo que distribuye las parejas de
etiquetas y campos de texto:
. . .
//Layout the labels in a panel
JPanel labelPane = new JPanel();
labelPane.setLayout(new GridLayout(0, 1));
labelPane.add(amountLabel);
labelPane.add(rateLabel);
labelPane.add(numPeriodsLabel);
labelPane.add(paymentLabel);

//Layout the text fields in a panel
JPanel fieldPane = new JPanel();
fieldPane.setLayout(new GridLayout(0, 1));
fieldPane.add(amountField);
fieldPane.add(rateField);
fieldPane.add(numPeriodsField);
fieldPane.add(paymentField);

//Put the panels in another panel, labels on left,
//text fields on right
JPanel contentPane = new JPanel();
contentPane.setBorder(BorderFactory.createEmptyBorder(20, 20, 20,
20));
contentPane.setLayout(new BorderLayout());
contentPane.add(labelPane);
contentPane.add(fieldPane, "East");

setContentPane(contentPane);
. . .
Podras haberte sorprendido de encontrar que las etiquetas se distribuyen
sin referencias a los campos de texto y, de hecho, estn en paneles
diferentes, se alinean correctamente con ellos. Esto es un efecto lateral de
los controladores de distribucin usados por el programa.

Como ilustra el diagrama, el programa usa dos controladores GridLayout,
uno para la columna de etiquetas y otro para la columna de campos de
texto. GridLayout garantiza que todos sus componentes tendrn el mismo
tamao, por eso todos los campos de texto tienen la misma altura y todas
las etiquetas tambin.
Para conseguir la alineacin de las etiquetas y los campos de texto, el
programa usa un tercer controlador de distribucin, un BorderLayout. Con
slo dos componentes como East y Center, BorderLayoutgarantiza que las
columnas tengan la misma altura. As las etiquetas y los campos de texto se
alinean.
Proporcionar un Campo de Password
Swing proporciona la clase JPasswordField, una subclase de JTextField,
para usarla en vez de un campo de texto cuando el texto introducido por el
usuario es una password. Por razones de seguridad, un campo de password
no muestra los caracteres tecleados por el usuario. En su lugar muestra
otros caracteres como asteriscos "*".
El ejemplo PasswordDemo descrito en Usar la clase SwingWorker usa
un JPasswordField. El program trae una pequea ventana para pedir al
usuario que teclee una password:

Aqu est el cdigo de PasswordDemo que crea y configura el campo de
password:
JPasswordField password = new JPasswordField(10);
password.setEchoChar('#');

password.addActionListener(showSwingWorkerDialog);
El argumento pasado al constructor de JPasswordField indica que el campo
debera tener 10 columnas de ancho. Por defecto un campo de password
muestra un asterico '*' por cada caracter tecleado. La llamada
a setEchoChar lo cambia por una almohadilla '#'. Finalmente el cdigo aade
un oyente de 'action' al campo de password. El mtodo actionPerformed del
oyente obtiene la password tecleada por el usuario y la verifica con este
cdigo:
public void actionPerformed(ActionEvent e) {
JPasswordField input = (JPasswordField)e.getSource();
char[] password = input.getPassword();
if (isPasswordCorrect(password))
JOptionPane.showMessageDialog(f, worker.get());
else
JOptionPane.showMessageDialog(f,
new JLabel("Invalid password."));
}
Este mtodo usa el mtodo getPassword del campo de password para
obtener el contenido del campo. Observa que getPassword devuelve un
array de caracteres. La informacin de un password no debera almacenarse
ni pasarse en strings porque stas no son seguras. Por eso no
uses getText o setText sobre un campo de password. En su lugar
usa getPassword o setPassword porque estos mtodos usan arrays de
caracteres en vez de strings.

Nota: El mtodo getPassword y su compaero, setPassword, no existan en
Swing 1.0.3 y anteriores. En estas versiones se debe
usar getText y setText. Nuestro programa debera almacenar cualquier
passwrod en un array de caracteres y convertirlo temporalmente a un string
cuando se llame a getText o a setText.

El API de TextField
Las siguientes tablas muestran los mtodos y constructores ms usados
de JTextField. Otros mtodos interesantes los proporcionan las
clases JComponent y Component.
Adems, podramos querer llamar a alguno de los mtodos definidos
por JTextComponent, la clase padre de JTextField. Puedes ver la
seccin: El API de los Componentes de Texto.
El API para usar campos de texto se divide en tres categoras:
Seleccionar u Obtener el Contenido de un Campo de Texto
Ajuste Fino de la apariencia de una Campo de Texto
Implementar la Funcionalidad de un Campo de Texto
Seleccionar u Obtener el Contenido de un Campo de Texto
Mtodo Propsito
JTextField()
JTextField(String)
JTextField(String, int)
JTextField(int)
JTextField(Document,
String, int)
Crea un ejemplar de JTextField, inicializando su contenido con
el texto especificado. El argumento int indica el nmero de
columnas. Esto se utiliza para calculo la anchura preferida del
componente y podra no ser el nmero real de columnas
mostradas.
void setText(String)
String getText()
Selecciona u obtiene el texto mostrado por el campo de texto.
Ajsute Fino de la Aperiencia del Campo de Texto
Mtodo Propsito
void setEditable(boolean)
boolean isEditable()
Selecciona u obtiene si el usuario puede editar el campo de
texto.
void setForeground(Color)
Color getForeground()
Selecciona u obtiene el color del texto dentro del campo de
texto.
void setBackground(Color);
Color getBackground()
Selecciona u obtiene el color del fondo del campo de texto.
void setFont(Font);
Font getFont()
Selecciona u obtiene la fuente usada por el campo de texto.
void setColumns(int);
int getColumns()
Selecciona u obtiene el nmero de columnas mostradas por
el campo de texto.
int getColumnWidth()
Obtiene la anchiura de las columnas del campo de texto.
Este valor los establece implcitamente la fuente elegida.
void
setHorizontalAlignment(int);
int getHorizontalAlignment()
Selecciona u obtiene cmo est alineado el texto
horizontalmente dentro de su rea. Podemos
usar JTextField.LEFT, JTextField.CENTER,
y JTextField.RIGHTcomo argumentos.
Implementar la Funcionalidad del Campo de Texto
Mtodo Propsito
void
addActionListener(ActionListener)
void
removeActionListener(ActionListener)
Aade o elimina un oyente de 'action'.
Document createDefaultModel()
Sobreescribe este mtodo para proporcionar al
campo de texto un documento personalizado.
Ejemplos que usan Text Fields
Esta tabla lista los ejemplos que usan JTextField y dnde encontrarlos.
Ejemplo Dnde se Describe Notas
TextDemo.java Esta pgina
Usa un textfield con un oyente de
'action'.
TextFieldDemo.java Esta pgina
Implementa dos campos diferentes con
validacin de pulsaciones.
PasswordDemo.java
Esta pgina y Usar
SwingWorkerClass
Usa un campos de password.
CustomDialog.java Cmo crear un Dilogo
Incluye un campo de texto cuyo valor es
comprobado.

@ ozito 1998

También podría gustarte