Textfield Validation in Java using LostFocus event

8.3k views Asked by At

I am validating two textfields using LostFocus event as follows:

textRegNo.addFocusListener(new FocusListener() {            
        @Override
        public void focusLost(FocusEvent arg0) {
            // TODO Auto-generated method stub
            regNo1=textRegNo.getText();
            Pattern pattern1 = Pattern.compile("^[A-Z]{2}[ -][0-9]{1,2}(?: [A-Z])?(?: [A-Z]*)? [0-9]{4}$");
            Matcher matcher1 = pattern1.matcher(regNo1);

            if (!matcher1.find()){
                JOptionPane.showMessageDialog(null, "Invalid Vehicle No!!!\n Vehicle no should be of the form MH 03 KS 2131!!");
            }                           
        }
        @Override
        public void focusGained(FocusEvent arg0) {
            // TODO Auto-generated method stub

        };
    }); 


textMobNo.addFocusListener(new FocusListener() {            
        @Override
        public void focusLost(FocusEvent arg0) {
            // TODO Auto-generated method stub
            mobNo1=textMobNo.getText();
            Pattern pattern2 = Pattern.compile("^[789]\\d{9}$");
            Matcher matcher2 = pattern2.matcher(mobNo1);

            System.out.println("'"+mobNo1+"'");
            if (!matcher2.find()){
                JOptionPane.showMessageDialog(null, "Phone no must be a 10 digit number!!");
            }                           
        }

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

        };
    });

My problem is that when i lose focus on 1st textfield and move that focus to the 2nd text filed error message gets printed for both the fields(MESSAGE inside IF block under both lostfocus event.) When i give wrong input into 1st textfield and move focus to 2nd field it should only print the error message for 1st text field. But its printing error for both.

1st textfield is textRegNo 2nd textfield is textMobNo

1

There are 1 answers

5
MadProgrammer On BEST ANSWER

The symptom of the problem revolves around this process.

  1. textMobNo gains focus...
  2. which causes textRegNo to lose focus...
  3. textRegNo is validated and found to be invalid, textRegNo now displays an error message...
  4. Focus is transferred to the dialog and...
  5. textMobNo loses focus (because the dialog gained focus)

You should avoid using focus as a means to validate fields if you can and instead use an InputVerifier

Simple example

import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.JTextComponent;

public class TestInputVerifier {

    public static void main(String[] args) {
        new TestInputVerifier();
    }

    public TestInputVerifier() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;
            JTextField field = new JTextField(20);
            field.setInputVerifier(new RegExpInputVerifier("^[A-Z]{2}[ -][0-9]{1,2}(?: [A-Z])?(?: [A-Z]*)? [0-9]{4}$"));
            add(field, gbc);

            field = new JTextField(20);
            field.setInputVerifier(new RegExpInputVerifier("^[789]\\d{9}$"));
            add(field, gbc);
        }

    }

    public class RegExpInputVerifier extends InputVerifier {

        private String expression;

        public RegExpInputVerifier(String expression) {
            this.expression = expression;
        }

        public String getExpression() {
            return expression;
        }

        @Override
        public boolean verify(JComponent input) {
            boolean verified = false;
            if (input instanceof JTextComponent) {
                JTextComponent field = (JTextComponent) input;
                String regNo1 = field.getText();
                Pattern pattern1 = Pattern.compile(expression);
                Matcher matcher1 = pattern1.matcher(regNo1);
            }
            return verified;
        }
    }
}