Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
package eventos;
public FrmSaludo() {
setSize(300,200);
setTitle("Saludo");
initComponents();
}
btnSaludo.setToolTipText("Botón de pulsación");
btnSaludo.setMnemonic('C');
btnSaludo.setText("Haga clic aquí");
// Manejador de eventos asociado con el botón
btnSaludo.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnSaludoActionPerformed(evt);
}
});
getContentPane().add(btnSaludo);
btnSaludo.setBounds(42, 90, 204, 30);
setLocationRelativeTo(null);
}
Se asigna un administrador de diseño que permite establecer la forma en que los componentes serán
distribuidos sobre el contenedor:
Se añaden los componentes al panel raíz del objeto FrmSaludo y se establece su posición en el
contenedor y su tamaño:
El método add del objeto Container devuelto por getContentPane permite añadir un
componente al contenedor, en este caso FrmSaludo. El método setBounds, heredado de la clase
java.awt.Component, permite establecer las coordenadas de la esquina superior izquierda de un
componente, su anchura y su altura.
Swing tiene un administrador de interfaz de usuario, UIManager, que controla la apariencia (look
and feel) de los componentes que forman una interfaz gráfica, que puede ser de estilo Windows, Motif
X-Window o Java. Lo normal es establecer el estilo propio del sistema, que es devuelto por el método
getSystemLookAndFeelClassName de UIManager, o bien el estilo Java (multiplataforma) que
es devuelto por getCrossPlatformLookAndFeelClassName. Para establecer uno de estos estilos,
se invoca al método setLookAndFeel:
package eventos;
public FrmConversor() {
setSize(300, 200);
setTitle("Conversión de temperaturas");
initComponents();
}
Un botón por omisión es aquel que tiene un borde más resaltado que los demás y que es
automáticamente pulsado cuando se pulsa la tecla Enter. Para informar al panel raíz del que será el
botón por omisión de entre todo los que contenga, hay que invocar al método setDefaultButton:
Cuando el usuario escribe en una caja de texto, cada pulsación produce un evento de tipo KeyEvent
que coloca en la cola de mensajes de la aplicación los mensajes keyPressed, keyTyped y
keyReleased. Para interceptar este tipo de eventos, se añade a cada una de las cajas de texto un
manejador de tipo KeyListener. El mensaje que se requiere interceptar es “se ha escrito un carácter:
keyTyped”. El método txtGradosKeyTyped guarda el identificador de la caja de texto en la
variable miembro objTextField, cuyo valor servirá para saber sobre qué caja de texto escribió el
usuario y actualizar a partir de este valor el contenido de la otra.
Una vez que el usuario haya escrito un valor en una caja de texto, su siguiente acción será pulsar la
tecla Enter, o lo que es lo mismo, hará clic en el botón Aceptar. Para que este botón pueda responder
al evento “clic” se le asocia un manejador de eventos de acción, en el método initComponents:
Las acciones que se ejecutarán cuando se haga clic sobre el botón Aceptar, se definen en el método
btnAceptarActionPerformed. Este método tiene que interrogar la variable miembro objTextField para
saber en qué caja de texto introdujo el usuario un nuevo valor y aplicar la fórmula de conversión
adecuada, visualizando el resultado de la conversión en la otra caja.
Cuando un componente posee el punto de inserción, se dice que dicho componente está enfocado o
que tiene el foco. Para enfocar un componente, el usuario puedo hacer clic sobre él o pulsando la
tecla Tab una o más veces hasta situar el foco sobre él. Para enfocar un componente cuando la
ventana de la aplicación se visualiza, se invoca al método requestFocus:
En la mayoría de las ocasiones se requiere que el contenido de una caja de texto sea seleccionado
automáticamente cuando recibe el foco. Para ello se asocia a cada caja de texto un manejador de
eventos FocusEvent. Para interceptar este tipo de eventos, se añade a cada caja de texto un
manejador de tipo FocusListener. El mensaje que interesa interceptar es: “foco ganado:
focusGained”. El código se inserta en el método initComponents:
package eventos;
public FrmConversor2() {
setSize(300, 200);
setTitle("Conversión de temperaturas");
initComponents();
}
En este nuevo diseño, luego de que el usuario modifica el contenido de una caja de texto y pulsa la
tecla Enter, se realiza el cálculo de la conversión y se actualiza la otra caja de texto. Para interceptar
la tecla Enter, se asocia un manejador de tipo ActionListener con el componente de texto que
recibe tal evento. En el método initComponents se encuentra el código:
Validar un campo de texto equivale a restringir su contenido al conjunto de caracteres válidos para
dicho campo. Si la validación de los datos se hace después de pulsar la tecla Enter en el componente
de texto (se produce el evento de acción ActionEvent), el campo podría contener datos no válidos,
aunque podrían ser validados antes de utilizarlos. En cambio si la validación se hace verificando la
validez de cada tecla pulsada (se genera un evento de pulsación KeyEvent), el campo de texto ya
estará validado una vez finalizado el ingreso de datos.
Cuando un componente de texto tiene el foco y el usuario pulsa una tecla se generan tres mensajes:
keyPressed (cuando se pulsa la tecla), keyTyped (cuando se escribe el carácter) y keyReleased
(cuando se suelta la tecla). Para que el componente responda deberá tener asociado un manejador de
eventos de tipo KeyListener, o lo que es lo mismo, de tipo KeyAdapter.
En esta aplicación se considera que el contenido de las cajas de texto será válido cuando sus
caracteres pertenezcan al siguiente conjunto: +-.1234567890. El signo + o – sólo puede aparecer al
principio del dato y éste sólo puede contener un punto decimal.
Para responder al evento “se soltó la tecla: keyReleased” se implementa el método
txtGradosKeyReleased, donde por cada pulsación:
- Obtiene el contenido actual de la caja de texto que genera el mensaje keyReleased.
- Lo almacena en una matriz de caracteres denominada fuente.
- Aplicando las reglas enunciadas en el párrafo previo, copia los caracteres válidos en otra matriz
denominada resultado.
- Reemplaza el contenido de la caja de texto con el contenido de resultado, sólo si algún carácter de
fuente no fue válido.
Los componentes Swing están basados en la arquitectura modelo-vista-controlador. En el caso de los campos de
texto, el modelo está definido por el documento de texto, la vista se refiere a cualquier perspectiva de ese
modelo y el controlador se corresponde con los manejadores de eventos.
Según esta arquitectura, para crear un campo validado hay que interceptar cada pulsación antes de que el
carácter sea insertado en el modelo, con el fin de insertar sólo los caracteres válidos. De esta forma la vista
nunca podrá mostrar datos no válidos.
El modelo (contenedor de texto) de un componente de texto es un objeto que implementa la interfaz
Document. En el nivel más elemental, el texto es modelado como una secuencia lineal de caracteres. Este
modelo es creado por el método createDefaultModel de JTextField cada vez que se crea un objeto de
esta clase.
package eventos;
modelo asociado con dicho objeto, que como se puede observar, será un objeto de la clase
PlainDocumentDouble.
La clase PlainDocumentDouble crea el contenedor de texto (el modelo). Esta clase hereda un método
llamado insertString que será invocado de forma automática por un objeto JTextFieldDouble cada
vez que haya que insertar un carácter en el contenedor de texto (porque el usuario pulsó una tecla), o
una cadena de caracteres (porque se invocó al método setText). Este método ha sido implementado
para que antes de insertar el carácter o la cadena de caracteres en el modelo, valide esta información.
Una vez realizada la validación, el método insertString de la clase JTextFieldDouble se limitará a llamar
al método insertString de la clase padre pasándole como argumento la información validada para
que sea insertada en el modelo y visualizada en la vista del objeto JTextFieldDouble.
package eventos;
ublic FrmConversor3() {
setSize(300, 200);
setTitle("Conversión de temperaturas");
initComponents();
}
getContentPane().add(txtGradosC);
txtGradosC.setBounds(132, 28, 144, 20);
lblGradosF.setText("Grados Farenheit");
getContentPane().add(lblGradosF);
lblGradosF.setBounds(12, 68, 104, 24);
txtGradosF.setText("32.00");
txtGradosF.setHorizontalAlignment(javax.swing.SwingConstants.RIGHT);
// Manejador de eventos asociado a la caja de texto
txtGradosF.addFocusListener(new java.awt.event.FocusAdapter() {
public void focusGained(java.awt.event.FocusEvent evt) {
txtGradosFocusGained(evt);
}
});
txtGradosF.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
txtGradosActionPerformed(evt);
}
});
getContentPane().add(txtGradosF);
txtGradosF.setBounds(132, 72, 144, 20);
setLocationRelativeTo(null);
}
} catch (NumberFormatException e) {
txtGradosC.setText("0.00");
txtGradosF.setText("32.00");
}
}