0

I have a simple login frame with a JTextField and a JPasswordField. When my frame loads the text of the JTextField is "Typ your login". I want to erase that text when the JTextField gets focus. It's the first element in my frame so it already has focus when I load the frame, but I want it to clear whenever I click on it or start typing in it. I tried a MouseListener, which works fine, but now I'd like to clear the JTextField from the moment I start typing. This is the code involving my problem:

import java.awt.FlowLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
import javax.swing.JPasswordField;
import javax.swing.JTextField;

public class TextFields extends JFrame {

    private static final long serialVersionUID = 1L;

    private JTextField login;
    private JPasswordField password;

    public TextFields() {
        super("Event handling");
        setLayout(new FlowLayout());

        login = new JTextField("Type your login", 20);
        password = new JPasswordField(20);
        add(login);
        add(password);

        LoginHandler handler = new LoginHandler();
        login.addMouseListener(handler);
    }

    private class LoginHandler implements ActionListener, MouseListener {       

        public void mouseClicked(MouseEvent e) {
            login.setText("");
        }

        @Override
        public void mouseEntered(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseExited(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void mouseReleased(MouseEvent e) {
            // TODO Auto-generated method stub

        }

        @Override
        public void focusLost(FocusEvent arg0) {
            // TODO Auto-generated method stub

        }
    }

    public static void main(String[] args) {
        TextFields test = new TextFields();
        test.setDefaultCloseOperation(EXIT_ON_CLOSE);
        test.setSize(250, 100);
        test.setVisible(true);

    }

}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373

2 Answers2

5

I don't know the canonical answer, but I've used a FocusListener for this issue, by calling selectAll() in the focusGained method. Don't use a MouseListener since this will fail if the user tabs into the field.

e.g.,

private class MyFocusListener extends FocusAdapter {
   @Override
   public void focusGained(FocusEvent fEvt) {
      JTextComponent component = (JTextComponent) fEvt.getSource();
      component.selectAll();
   }
}

and

login.addFocusListener(new MyFocusListener());
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
5

Conceptually, what you really want is to set a “placeholder” or “prompt” for your text field, rather than changing the actual text in the field. Such an abstraction would also give you features like being able to style the prompt a light gray color.

A normal JTextField does not support this, but you could write your own subclass, or use a library. This answer explains how to use the SwingX library to accomplish that. Basically, just import org.jdesktop.swingx.prompt.PromptSupport; and add this line:

PromptSupport.setPrompt("Type your login", login);
Community
  • 1
  • 1
Rory O'Kane
  • 29,210
  • 11
  • 96
  • 131
  • +1 for SwingX suggestion. It might worth to take a look to [JXLoginPane](http://stackoverflow.com/questions/tagged/jxloginpane) exemplified [here](http://stackoverflow.com/a/25047554/1795530) and [here](http://stackoverflow.com/a/26147250/1795530) to avoid re-inventing the wheel by using an existent API to Swing login-based applications. – dic19 Nov 08 '14 at 03:07