Transferir el foco: transferFocus

De ChuWiki

Cuando creamos un panel Java con varios campos de texto para introducir datos, pulsando la tecla <tab> y <ctrl-tab> podemos hacer que el cursor vaya pasando de un campo de texto a otro.

Sin embargo, a veces nos gustaría que según metemos un dato en un campo de texto y pulsamos <enter>, el foco pase al siguiente campo de texto. Para conseguir esto, tenemos el método transferFocus(). Llamando a este método en un Component -por ejemplo, uno de los campos de texto-, el foco se transmitirá al siguiente componente del panel que pueda aceptar el foco.

Para que al pulsar <enter> en un campo de texto se llame a tranferFocus(), debemos añadir un ActionListener a dicho campo de texto y hacer la llamada.

El siguiente ejemplo crea una ventana con tres etiquetas y tres campos de texto. A cada campo de texto se le añade el ActionListener de forma que cuando se pulse <enter> en él, tranfiera el foco al siguiente.

/**
 * Ejemplo de como transferir desde código el foco de unos componentes a otros.
 */
package com.chuidiang.ejemplos.transfer_focus;

import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

/**
 * Ejemplo de cómo transferir el foco de un campo de texto a otro cuando se
 * pulsa la tecla <enter>
 * @author chuidiang
 *
 */
public class PruebaTransferFocus {
    /**
     * Crea una instancia de esta clase.
     * @param args
     */
    public static void main(String[] args) {
        new PruebaTransferFocus();
    }

    /**
     * Crea una ventana con tres etiquetas y tres campos de texto. Añade a cada
     * campo de texto un ActionListener que transfiere el foco al siguiente campo
     * de texto.
     */
    public PruebaTransferFocus() {
        // Creación de la ventana.
        JFrame v = new JFrame("Prueba LayoutMangager");
        v.getContentPane().setLayout(new GridLayout(3, 2));
        for (int i = 0; i < 3; i++) {
            v.getContentPane().add(new JLabel("etiqueta " + (i + 1)));
            JTextField tf = new JTextField(10);
            v.getContentPane().add(tf);
            
            // Se añade el ActionListener a los campos de texto
            tf.addActionListener(tranfiereElFoco);
        }
        v.pack();
        v.setVisible(true);
        v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }

    /**
     * Encargada de transferir el foco al siguiente componente.
     */
    private ActionListener  tranfiereElFoco = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            // Se transfiere el foco al siguiente elemento.
            ((Component) arg0.getSource()).transferFocus();
        }
    };
}

Otra opción que tenemos es indicarle al panel principal de las ventanas qué teclas queremos que sean las que sirvan para transferir el foco. Para ello, se llama al método setFocusTraversalKeys(), pasándole un entero que indica en qué sentido queremos que se transfiera el foco y el conjunto de teclas. En el siguiente ejemplo se añaden la tecla <tab> y la <enter> para tranferir el foco al siguiente campo. Se añade el <tab> para no perder este comportamiento por defecto.

/**
 * Ejemplo de como transferir desde código el foco de unos componentes a otros.
 */
package com.chuidiang.ejemplos.transfer_focus;

import java.awt.AWTKeyStroke;
import java.awt.Component;
import java.awt.DefaultFocusTraversalPolicy;
import java.awt.FocusTraversalPolicy;
import java.awt.GridLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.WindowConstants;

/**
 * Ejemplo de cómo transferir el foco de un campo de texto a otro cuando se
 * pulsa la tecla <enter>
 * @author chuidiang
 *
 */
public class PruebaTransferFocus {
    /**
     * Crea una instancia de esta clase.
     * @param args
     */
    public static void main(String[] args) {
        new PruebaTransferFocus();
    }

    /**
     * Crea una ventana con tres etiquetas y tres campos de texto. Añade a cada
     * campo de texto un ActionListener que transfiere el foco al siguiente campo
     * de texto.
     */
    public PruebaTransferFocus() {
        // Creación de la ventana.
        JFrame v = new JFrame("Prueba LayoutMangager");
        v.getContentPane().setLayout(new GridLayout(3, 2));

        // Conjunto de teclas que queremos que sirvan para pasar el foco 
        // al siguiente campo de texto: ENTER y TAB
        Set<AWTKeyStroke> teclas = new HashSet<AWTKeyStroke>();
        teclas.add(AWTKeyStroke.getAWTKeyStroke(
                KeyEvent.VK_ENTER, 0));
        teclas.add(AWTKeyStroke.getAWTKeyStroke(
                KeyEvent.VK_TAB, 0));
        
        // Se pasa el conjunto de teclas al panel principal 
        v.getContentPane().setFocusTraversalKeys(
                KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, 
                teclas);
        
        // Construcción de la ventana
        for (int i = 0; i < 3; i++) {
            v.getContentPane().add(new JLabel("etiqueta " + (i + 1)));
            JTextField tf = new JTextField(10);
            v.getContentPane().add(tf);
        }
        
        // Se hace visible.
        v.pack();
        v.setVisible(true);
        v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}