6

I have a login form where a user can enter his credentials to login. I have a JLabel that serves to display the text telling the user that the user name cannot be empty. This label is display after a user click the login button when the text field is empty.

I want that the moment the user starts typing in the text field the label with the information should disappear.How do I achieve this behavior?

Here is the code:

public class JTextFiledDemo {

private JFrame frame;

JTextFiledDemo() {
    frame = new JFrame();
    frame.setVisible(true);
    frame.setSize(300, 300);
    frame.setLayout(new GridLayout(4, 1));
    frame.setLocationRelativeTo(null);
    iniGui();
}

private void iniGui() {

    JLabel error = new JLabel(
            "<html><font color='red'> Username cannot be empty!<></html>");

    error.setVisible(false);
    JButton login = new JButton("login");
    JTextField userName = new JTextField(10);

    frame.add(userName);
    frame.add(error);
    frame.add(login);
    frame.pack();

    login.addActionListener((ActionEvent) -> {
        if (userName.getText().equals("")) {
            error.setVisible(true);
        }
    });

}

public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            JTextFiledDemo tf = new JTextFiledDemo();
        }
    });
 }
}
CN1002
  • 1,115
  • 3
  • 20
  • 40

3 Answers3

5

You have to create DocumentListener:

    DocumentListener dl = new DocumentListener()
    {
        @Override
        public void insertUpdate(DocumentEvent de)
        {
            error.setVisible(false);
        }

        @Override
        public void removeUpdate(DocumentEvent de)
        {
            //
        }

        @Override
        public void changedUpdate(DocumentEvent de)
        {
            error.setVisible(false);
        }
    };

then for your text fields:

login.getDocument().addDocumentListener(dl);
Kuba
  • 839
  • 7
  • 16
4

For that purposes you need to use DocumentListener on your JTextField, here is tutorial.

As example:

userName.getDocument().addDocumentListener(new DocumentListener() {
    @Override
    public void insertUpdate(DocumentEvent de){
       event(de);
    }

    @Override
    public void removeUpdate(DocumentEvent de) {
        event(de);
    }

    @Override
    public void changedUpdate(DocumentEvent de){
        event(de);
    }

    private void event(DocumentEvent de){
        error.setVisible(de.getDocument().getLength() == 0);
        // as mentioned by nIcE cOw better to use Document from parameter
        frame.revalidate();
        frame.repaint();
    }
});

error must be final(for java lower than 8 version).

Also at start your field is empty, so may be need to use setVisible(true) on error label.

alex2410
  • 10,904
  • 3
  • 25
  • 41
  • Thought upvoted the answer, but why `error` has to be final for `Java 1.7 and below` Instead, `error JLabel` should be instance variable, in order to avoid, it being `final` – nIcE cOw Apr 20 '15 at 09:21
  • @nIcEcOw lower than 8 version, in 1.8 it may not be final. In lower versions it must be final because it is local variable, or declared as instance variable – alex2410 Apr 20 '15 at 09:22
  • `final` variable is needed for a reason, but not for the purpose you described in this post. If `error JLabel` is the instance variable, then there is no need to declare it as being `final`. – nIcE cOw Apr 20 '15 at 09:24
  • @nIcEcOw you are right, but here `error` isn't instance variable. – alex2410 Apr 20 '15 at 09:25
  • 1
    Moreover, instead of using `getText()` , one should be using `( ( Docuemnt ) de.getDocument () ).getLength ();`. Let the argument decide, which `JTextComponent` is currently in question. – nIcE cOw Apr 20 '15 at 09:30
  • Yeah, better to use document length from parameter. – alex2410 Apr 20 '15 at 09:33
  • I have resorted to using `DocumentListener` as mentioned by @Kuba and @alex2410. It is solved. Allow me to say thanks for mentioning a couple of things that I had missed. – CN1002 Apr 20 '15 at 11:04
0

You can add a keyListener in the input filed

userName.addKeyListener(new KeyListener() {

    @Override
    public void keyTyped(KeyEvent arg0) {

    }

    @Override
    public void keyReleased(KeyEvent arg0) {

    }

    @Override
    public void keyPressed(KeyEvent arg0) {
        error.setVisible(false);
    }
});
Saif
  • 6,804
  • 8
  • 40
  • 61
  • i don't see the problem with my solution. Can anyone kindly enlighten me – Saif Apr 20 '15 at 09:04
  • There are keys, that will not input character to field, but key listener action will be called – Kuba Apr 20 '15 at 09:05
  • Downvote for using `KeyListener`. In that case you need to use `DocumentListener`. – alex2410 Apr 20 '15 at 09:07
  • @Saif: `KeyListener`s are way too low level for `Swing`. For the purpose of what is asked in the question, `DocumentListener` is the preferred choice. Though if one wants to catch the input, before the input goes to the `Document`, `DocumentFilter` is used. Hope this might help you gain more insight, as to why the answer is not to the mark. Do remember to KEEP SMILING :-) as you learn – nIcE cOw Apr 20 '15 at 09:19
  • 1
    @nIcEcOw i am still smiling.Thanks for your explanation. I added that comment to know, what is actually wrong.? now as i understand the real reason it is easy for me. Thanks again. – Saif Apr 20 '15 at 09:38