Eventos de Usuario: FocusListener

FocusListener

El foco describe el componente que esta activo para entradas de teclado. Este puede ser ganado o perdido, y esto representa también un evento de usuario. La idea se me hace similar a el reflector llamado vector que recibe a un presentador y como si fuera un componente que recibe esa atención.

java.awt.event

Interface FocusListener


Métodos:

  • void focusGained(FocusEvent e)
    • Se invoca cuando un componente gana el foco del teclado.
  • void focusLost(FocusEvent e)
    • Se invoca cuando un componente pierde el foco del teclado.
Pequeño ejemplo: al seleccionar(ganar el foco) un campo de texto aparece un mensaje con una sugerencia y al perderlo este se borra:
  1. import java.awt.*;
  2. import java.awt.event.FocusEvent;
  3. import java.awt.event.FocusListener;
  4. import javax.swing.*;
  5. public class EjemploFoco extends JFrame implements FocusListener{
  6.     JPanel panel = new JPanel();
  7.     FlowLayout flujo = new FlowLayout();
  8.     JLabel nombre = new JLabel("Nombre:", JLabel.LEFT);
  9.     JTextField campo = new JTextField(20);
  10.     JLabel mensaje = new JLabel("                                         ");
  11.     JPanel panel2 = new JPanel();
  12.     JLabel apellido = new JLabel("Apellido:", JLabel.LEFT);
  13.     JTextField campo2 = new JTextField(20);
  14.     JLabel mensaje2 = new JLabel("                                         ");
  15.     public EjemploFoco(){
  16.         super("EJemplo de FocusListener");
  17.         setSize(470,140);
  18.         setLocationRelativeTo(null);
  19.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  20.        
  21.         panel.setLayout(flujo);
  22.         panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 0, 20));
  23.         panel.add(nombre);
  24.         campo.addFocusListener(this);
  25.         panel.add(campo);
  26.         panel.add(mensaje);
  27.        
  28.         panel2.setLayout(flujo);
  29.         panel2.setBorder(BorderFactory.createEmptyBorder(0, 20, 20, 20));
  30.         panel2.add(apellido);
  31.         campo2.addFocusListener(this);
  32.         panel2.add(campo2);
  33.         panel2.add(mensaje2);
  34.        
  35.         GridLayout grilla = new GridLayout(2,1);
  36.         setLayout(grilla);
  37.         add(panel);add(panel2);
  38.         //pack();
  39.         setVisible(true);
  40.     }
  41.     @Override
  42.     public void focusGained(FocusEvent e) {
  43.         if(e.getSource() == campo){
  44.             mensaje.setText("<--Escribe tu monbre.");
  45.         }
  46.         if(e.getSource() == campo2){
  47.             mensaje2.setText("<--Escribe tu Apellido.");
  48.         }
  49.        
  50.     }
  51.     @Override
  52.     public void focusLost(FocusEvent e) {
  53.         if(e.getSource() == campo){
  54.             mensaje.setText("                                         ");
  55.         }
  56.         if(e.getSource() == campo2){
  57.             mensaje2.setText("                                         ");
  58.         }
  59.        
  60.     }
  61.     public static void main(String[] dario){
  62.         new EjemploFoco();
  63.     }
  64. }


ComponentEvent, FocusEvent y métodos propios

Class ComponentEvent

java.lang.Object
java.util.EventObject
java.awt.AWTEvent
javax.swing.JComponent
java.awt.event.ComponentEvent

Class FocusEvent

java.lang.Object
java.util.EventObject
java.awt.AWTEvent
javax.swing.JComponent
java.awt.event.ComponentEvent
java.awt.event.FocusEvent
Lo que nos interesa de estas clases es el objeto FocusEvent e que indicamos como parametro en los métodos implementados por la interface FocusListener.
  • public void focusGained(FocusEvent e) {}
  • public void focusGLost(FocusEvent e) {}
Y en particular sus métodos:
  • Class ComponentEvent
    • getComponent()
      • Devuelve el componente que generó el evento.
  • Class FocusEvent
    • getOppositeComponent()
      • Devuelve el componente implicado en este cambio de enfoque, que perdio el foco.
  • isTemporary()
    • Devuelve un parámetro String, que identifica a este evento.

  • Class JComponent
    • requestFocus()
      • Podemos pedir que tenga el foco un componente como JButton.

  • Segundo Ejemplo

    1. import java.awt.*;
    2. import java.awt.event.FocusEvent;
    3. import java.awt.event.FocusListener;
    4. import javax.swing.*;
    5. public class CalculadoraFoco extends JFrame implements FocusListener {
    6.     FlowLayout flujo = new FlowLayout();
    7.     JTextField num1 = new JTextField(10);
    8.     JLabel mas = new JLabel(" + ");
    9.     JTextField num2 = new JTextField(10);
    10.     JLabel igual = new JLabel(" = ");
    11.     JTextField resultado = new JTextField("0", 8);
    12.     public CalculadoraFoco(){
    13.         super("Calculadora a través de FocusListener");
    14.         setLocationRelativeTo(null);
    15.         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    16.        
    17.         setLayout(flujo);
    18.         num1.addFocusListener(this);
    19.         add(num1); add(mas);
    20.         num2.addFocusListener(this);
    21.         add(num2); add(igual);
    22.         resultado.setEnabled(false);
    23.         add(resultado);
    24.        
    25.         pack();
    26.         setVisible(true);
    27.     }
    28.     @Override
    29.     public void focusGained(FocusEvent e) {
    30.         try{
    31.             float total = Float.parseFloat( num1.getText() )
    32.                     Float.parseFloat( num2.getText() );
    33.             resultado.setText(" " total);
    34.         }catch(NumberFormatException em){
    35.             num1.setText("0");
    36.             num2.setText("0");
    37.             resultado.setText("0");
    38.         }
    39.     }
    40.     @Override
    41.     public void focusLost(FocusEvent e) {
    42.         focusGained(e);
    43.     }
    44.     public static void main(String[] args) {
    45.         new CalculadoraFoco();
    46.     }
    47. }
    Una pequeña calculadora que al ganar o perder el foco en nuestros JtextField se calcula el resultado de la suma automaticamente al pasar por otro campo de texto. Tambien podemos usar "tab" para pasar al siguiente y "shift+tab" para regresar.
    Nuestros campos de textos regresan un String que lo pasamos a Float con el método parseFloat y como parametro recuperamos el texto ingresado. Como también podemos escribir una letra u otro caracter incorrecto se puede producir una excepción maneja por NumberFormatException y en ese caso reseteamos todos los valores a "0".

    Ejemplo de The Java™ Tutorials

    El desafio recrear algo similar a lo propuesto en los tutoriales oficiales de Java
    El código es el siguiente:

    1. package eventos;
    2. import java.util.Vector;
    3. import java.awt.*;
    4. import java.awt.event.*;
    5. import javax.swing.*;
    6. public class FocusEventDemo extends JFrame implements FocusListener {
    7.     final static String newline = "\n";
    8.     final int numItems = 15;
    9.     JTextArea mostrar;
    10.    
    11.     //Constructor que configura el titulo cuando lo llamen.
    12.     public FocusEventDemo(String nombreTitulo) {
    13.         super(nombreTitulo);
    14.     }
    15.      
    16.     public void agregarComponentesPanel(final Container pane) {
    17.         GridBagLayout grilla = new GridBagLayout();
    18.         pane.setLayout(grilla);
    19.          
    20.         GridBagConstraints c = new GridBagConstraints();
    21.          
    22.         c.fill = GridBagConstraints.HORIZONTAL;
    23.         c.weightx = 1.0;  //Hace la columna lo más ancho posible.
    24.         JTextField campoTexto = new JTextField("Un Campo de Texto");
    25.         campoTexto.setMargin(new Insets(0,2,0,2));
    26.         campoTexto.addFocusListener(this);
    27.         grilla.setConstraints(campoTexto, c);
    28.         add(campoTexto);
    29.        
    30.         c.fill = GridBagConstraints.NONE;
    31.         c.weightx = 0.1;  //Ensancha un poco cualquier otra columna.
    32.         JLabel etiqueta = new JLabel("Una Etiqueta:");
    33.         etiqueta.setBorder(BorderFactory.createEmptyBorder(0,5,0,5));
    34.         etiqueta.addFocusListener(this);
    35.         grilla.setConstraints(etiqueta, c);
    36.         add(etiqueta);
    37.          
    38.         String prefijoCombo = "Item de ComboBox #";
    39.         Vector<String> vector = new Vector<String>(numItems);
    40.         for (int i = 0; i < numItems; i++)
    41.             vector.addElement(prefijoCombo i);
    42.         JComboBox<String> comboBox = new JComboBox<String>(vector);
    43.         comboBox.addFocusListener(this);
    44.         grilla.setConstraints(comboBox, c);
    45.         add(comboBox);
    46.          
    47.         c.gridwidth = GridBagConstraints.REMAINDER;
    48.         JButton boton = new JButton("Un Botón");
    49.         boton.addFocusListener(this);
    50.         grilla.setConstraints(boton, c);
    51.         add(boton);
    52.          
    53.         c.weightx = 0.0;
    54.         c.weighty = 0.1;
    55.         c.fill = GridBagConstraints.BOTH;
    56.         String prefijoLista = "Item de la Lista #";
    57.         Vector<String> listaVector = new Vector<String>(numItems);
    58.         for (int i = 0; i < numItems; i++) {
    59.             listaVector.addElement(prefijoLista i);
    60.         }
    61.         JList<String> lista = new JList<String>(listaVector);
    62.         lista.setSelectedIndex(1); //Es más fácil ver el cambio de enfoque, si se selecciona un elemento.
    63.         lista.addFocusListener(this);
    64.         JScrollPane scrollPaneLista = new JScrollPane(lista);
    65.          
    66.         grilla.setConstraints(scrollPaneLista, c);
    67.         add(scrollPaneLista);
    68.          
    69.         c.weighty = 1.0; //Hace esta fila tan alto como sea posible.
    70.         c.gridheight = GridBagConstraints.REMAINDER;
    71.         mostrar = new JTextArea();
    72.         mostrar.setEditable(false);
    73.         //El método setRequestFocusEnabled impide que un componente de ser seleccionable
    74.         //pero todavía puede obtener el enfoque a través del teclado, probar con "tab"
    75.         mostrar.setRequestFocusEnabled(false);
    76.         mostrar.addFocusListener(this);
    77.         JScrollPane scrollPaneArea = new JScrollPane(mostrar);
    78.          
    79.         grilla.setConstraints(scrollPaneArea, c);
    80.         add(scrollPaneArea);
    81.         setPreferredSize(new Dimension(450, 450));
    82.         ((JPanel)pane).setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
    83.     }
    84.     //Métodos de la interface FocusListener
    85.     public void focusGained(FocusEvent e) {
    86.         mostrarMensaje("Foco ganado", e);
    87.     }
    88.      
    89.     public void focusLost(FocusEvent e) {
    90.         mostrarMensaje("Foco perdido", e);
    91.     }
    92.    
    93.    
    94.     void mostrarMensaje(String prefijo, FocusEvent e) {
    95.         mostrar.append(prefijo (e.isTemporary() ? " (temporary):" : ":") );
    96.         mostrar.append(e.getComponent().getClass().getName() );
    97.         mostrar.append("; Componente Anterior: " (e.getOppositeComponent() != null ? e.getOppositeComponent().getClass().getName() : "ninguno") );
    98.         mostrar.append( newline);
    99.         mostrar.setCaretPosition(mostrar.getDocument().getLength());
    100.     }
    101.      
    102.     // Crear la GUI y la muestra. Para la seguridad del hilo, este método debe ser invocado desde el
    103.     // el hilo de distribución de eventos.
    104.     private static void crearYMostrarGUI() {
    105.         //Crear y da la configuracion básica de la ventana.
    106.         FocusEventDemo marco = new FocusEventDemo("Demostración de FocusListener");
    107.         marco.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    108.         //Configura el contenido del panel con el método "agregarComponentesPanel(final Container pane).
    109.         marco.agregarComponentesPanel(marco.getContentPane());
    110.          
    111.         //Enpaquetamos y hacemos visible la ventana.
    112.         marco.pack();
    113.         marco.setVisible(true);
    114.     }
    115.      
    116.     public static void main(String[] args) {
    117.         /* Podemos elegir alguno de los Look and Feel comentando el otro. */
    118.         try {
    119.             UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    120.             //UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
    121.         } catch (UnsupportedLookAndFeelException ex) {
    122.             ex.printStackTrace();
    123.         } catch (IllegalAccessException ex) {
    124.             ex.printStackTrace();
    125.         } catch (InstantiationException ex) {
    126.             ex.printStackTrace();
    127.         } catch (ClassNotFoundException ex) {
    128.             ex.printStackTrace();
    129.         }
    130.        
    131.         //Programa una tarea para el hilo de distribución de eventos:
    132.         //La interfaz Runnable y el método run que llama a nuestro método.
    133.         javax.swing.SwingUtilities.invokeLater(new Runnable() {
    134.             public void run() {
    135.                 crearYMostrarGUI();
    136.             }
    137.         });
    138.     }
    139. }

    Mi resultado:

    No hay comentarios:

    Publicar un comentario