2012-05-27 42 views
12

Cuando carga mi aplicación, que se hace usando netbeans, el primer JTextField se enfoca automáticamente, y en este JTextField, escribí "Ingrese su nombre de usuario", desaparecerá cuando el usuario haga clic en este campo, pero cuando la aplicación está cargada, este campo está enfocado, significa que no puedo ver "Ingrese su nombre de usuario", ¿cómo desenfocarlo en el inicio?Cómo desenfocar un JTextField

+0

Theres 2 JTextFields, primero para nombre de usuario, en segundo lugar para la contraseña, y una JMenuItem llamado Entrar, el momento en que ejecutar la aplicación, la primera JTextField está enfocado, no quiero que –

+0

BTW - si el nombre de usuario para cada aplicación. la instalación * se espera * sea constante, solo complete el campo de nombre de usuario con el valor predeterminado y deje que la pestaña del usuario vaya al siguiente campo si es correcto. Si está * garantizado * para ser constante, rellene el campo y desactívelo. No ** será ** enfocable, y el foco irá al segundo campo por defecto. –

Respuesta

14

Un inicio de sesión se realiza mejor en un diálogo modal, pero que presenta problemas en que el método requestFocusInWindow() hay que llamar después el componente es visible, pero que está bloqueado por el hecho de que el diálogo es modal!

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

Login with focused password field

Nota: Esa es la forma en que aparece antes de que el usuario haga nada. El campo de contraseña está enfocado por defecto.

package test.t100.t001; 

import java.awt.BorderLayout; 
import java.awt.GridLayout; 

import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JPasswordField; 
import javax.swing.JTextField; 
import javax.swing.SwingConstants; 
import javax.swing.SwingUtilities; 
import javax.swing.event.AncestorEvent; 
import javax.swing.event.AncestorListener; 

public class LoginRequired { 

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

     f.setSize(400, 300); 
     f.setResizable(false); 
     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.RIGHT)); 
     labels.add(new JLabel("Password", SwingConstants.RIGHT)); 
     p.add(labels, BorderLayout.WEST); 

     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); 

     //LayoutManager l = new GroupLayout(p); 
     //p.setLayout(l); 
     JOptionPane.showMessageDialog(
      frame, p, "Log In", JOptionPane.QUESTION_MESSAGE); 
    } 

    /** 
    * @param args none 
    */ 
    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable(){ 
      @Override 
      public void run() { 
       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) {} 
} 
+0

hmmm mis palabras también +1 – mKorbel

+0

@AloneInTheDark Esa es una pregunta separada que debe formularse por separado pregunta. –

4

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

Pero me gustaría sugerir no alterar el sistema de enfoque nativo, en lugar setText(String s) en el JTextField después initComponents() llamada en el constructor (se supone que en NetBeans).

lectura adicional opcional: How to Use the Focus Subsystem

+0

¿Qué sucede si tengo que hacer clic en un JMenuItem para iniciar sesión?Usé requestFocusInWindow() en otro elemento, pero en el momento en que hago clic en ese JMenuItem, el JTextField se enfoca, la segunda vez que hago clic en ese JMenuItem, el JTextField no está enfocado, funciona más tarde, pero la primera vez no –

+0

¿Lo intentas? 'nextFocusableComponent' propiedad en NetBeans editor de propiedades para su' JMenuItem'? – Asif

+0

Lo arreglé, utilicé tu código dos veces, en el inicio, y cuando hago clic en el Jmenuitem, gracias –

3

Creo que dar el enfoque del teclado al campo de nombre de usuario es el comportamiento correcto, suponiendo que eso es lo que el usuario debe hacer primero. En vez de despejar el enfoque, ¿por qué no está claro sólo después de que el usuario escribe algo ?:

import java.awt.*; 
import javax.swing.*; 
import javax.swing.text.Document; 

public class PlaceholderTextField extends JTextField { 

    public static void main(final String[] args) { 
     final PlaceholderTextField tf = new PlaceholderTextField(""); 
     tf.setColumns(20); 
     tf.setPlaceholder("All your base are belong to us!"); 
     final Font f = tf.getFont(); 
     tf.setFont(new Font(f.getName(), f.getStyle(), 30)); 
     JOptionPane.showMessageDialog(null, tf); 
    } 

    private String placeholder; 

    public PlaceholderTextField() { 
    } 

    public PlaceholderTextField(
     final Document pDoc, 
     final String pText, 
     final int pColumns) 
    { 
     super(pDoc, pText, pColumns); 
    } 

    public PlaceholderTextField(final int pColumns) { 
     super(pColumns); 
    } 

    public PlaceholderTextField(final String pText) { 
     super(pText); 
    } 

    public PlaceholderTextField(final String pText, final int pColumns) { 
     super(pText, pColumns); 
    } 

    public String getPlaceholder() { 
     return placeholder; 
    } 

    @Override 
    protected void paintComponent(final Graphics pG) { 
     super.paintComponent(pG); 

     if (placeholder.length() == 0 || getText().length() > 0) { 
      return; 
     } 

     final Graphics2D g = (Graphics2D) pG; 
     g.setRenderingHint(
      RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 
     g.setColor(getDisabledTextColor()); 
     g.drawString(placeholder, getInsets().left, pG.getFontMetrics() 
      .getMaxAscent() + getInsets().top); 
    } 

    public void setPlaceholder(final String s) { 
     placeholder = s; 
    } 

} 

Si realmente desea eliminar el foco, algunas opciones:

  • component.setFocusable(false);
  • KeyboardFocusManager.getCurrentKeyboardFocusManager().focusNextComponent();
  • KeyboardFocusManager.getCurrentKeyboardFocusManager().clearGlobalFocusOwner();
3
textField.setFocusable(false); 
textField.setFocusable(true); 

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

(no probado en una interfaz gráfica de usuario con sólo un componente enfocable :))

Cuestiones relacionadas