Saltar al contenido

Cómo desenfocar un JTextField

Nuestros investigadores estrellas han agotado sus depósitos de café, buscando noche y día por la solución, hasta que Daniella halló el arreglo en Beanstalk así que ahora la comparte con nosotros.

Solución:

Sería mejor realizar un inicio de sesión en un diálogo modal, pero eso presenta problemas en el sentido de que el método requestFocusInWindow() debe ser llamado después el componente es visible, pero eso está bloqueado por el hecho de que el diálogo es modal.

Este ejemplo utiliza Rob Camick RequestFocusListener (como se presenta en Dialog Focus) para administrar el enfoque después de que el diálogo sea visible.

Iniciar sesión con el campo de contraseña enfocado

Nota: Así es como aparece antes de que el usuario haga algo. El campo de contraseña está enfocado por defecto.

import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;

public class LoginRequired 

    LoginRequired() 
        JFrame f = new JFrame("Login Required");
        f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        f.setResizable(false);
        f.setSize(400, 300); // not recommended, but used here for convenience
        f.setLocationByPlatform(true);
        f.setVisible(true);

        showLogin(f);
    

    private void showLogin(JFrame frame) 
        JPanel p = new JPanel(new BorderLayout(5,5));

        JPanel labels = new JPanel(new GridLayout(0,1,2,2));
        labels.add(new JLabel("User Name", SwingConstants.TRAILING));
        labels.add(new JLabel("Password", SwingConstants.TRAILING));
        p.add(labels, BorderLayout.LINE_START);

        JPanel controls = new JPanel(new GridLayout(0,1,2,2));
        JTextField username = new JTextField("Joe Blogs");
        controls.add(username);
        JPasswordField password = new JPasswordField();
        password.addAncestorListener(new RequestFocusListener(false));
        controls.add(password);
        p.add(controls, BorderLayout.CENTER);

        JOptionPane.showMessageDialog(
            frame, p, "Log In", JOptionPane.QUESTION_MESSAGE);
        System.out.println("User Name: " + username.getText());
        System.out.println("Password: " + new String(password.getPassword()));
    

    public static void main(String[] args) 
        SwingUtilities.invokeLater(() -> 
            new LoginRequired();
        );
    


/**
 *  Convenience class to request focus on a component.
 *
 *  When the component is added to a realized Window then component will
 *  request focus immediately, since the ancestorAdded event is fired
 *  immediately.
 *
 *  When the component is added to a non realized Window, then the focus
 *  request will be made once the window is realized, since the
 *  ancestorAdded event will not be fired until then.
 *
 *  Using the default constructor will cause the listener to be removed
 *  from the component once the AncestorEvent is generated. A second constructor
 *  allows you to specify a boolean value of false to prevent the
 *  AncestorListener from being removed when the event is generated. This will
 *  allow you to reuse the listener each time the event is generated.
 */
class RequestFocusListener implements AncestorListener

    private boolean removeListener;

    /*
     *  Convenience constructor. The listener is only used once and then it is
     *  removed from the component.
     */
    public RequestFocusListener()
    
        this(true);
    

    /*
     *  Constructor that controls whether this listen can be used once or
     *  multiple times.
     *
     *  @param removeListener when true this listener is only invoked once
     *                        otherwise it can be invoked multiple times.
     */
    public RequestFocusListener(boolean removeListener)
    
        this.removeListener = removeListener;
    

    @Override
    public void ancestorAdded(AncestorEvent e)
    
        JComponent component = e.getComponent();
        component.requestFocusInWindow();

        if (removeListener)
            component.removeAncestorListener( this );
    

    @Override
    public void ancestorMoved(AncestorEvent e) 

    @Override
    public void ancestorRemoved(AncestorEvent e) 

textField.setFocusable(false);
textField.setFocusable(true);

Si, y solo si, textField tenía el foco, el siguiente componente en orden de tabulación obtendrá el foco automáticamente. El efecto es el mismo que pulsar TAB.

(no probado en una GUI con solo un componente enfocable :))

Usar requestFocusInWindow() para establecer el enfoque en algún otro componente en lugar de su JTextfield primero.

pero yo sugeriría no alterar el sistema de enfoque nativo, en lugar setText(String s) sobre el JTextField después initComponents() llamar en el constructor (se supone que está en netbeans).

Lectura opcional adicional: Cómo usar el subsistema de enfoque

Te mostramos las reseñas y valoraciones de los lectores

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *