javaswingjtextfieldinputverifier

Input Verifier on JTextField returns incorrect


This is my code, I have two text fields, tf1 and tf2 :

public class MyInputVerifier extends InputVerifier {
@Override
public boolean verify(JComponent input) {
    String name = input.getName();
    if (name.equals("tf1")) {
        System.out.println("in tf1");
        String text = ((JTextField) input).getText().trim();
        if (text.matches(".*\\d.*")) return false;       // have digit
    }
    else if (name.equals("tf2")) {
        System.out.println("in tf2");
        String text = ((JTextField) input).getText().trim();
        if (isNumeric2(text)) return true;
    }
    return false;
}

public boolean isNumeric2(String str) {
    try {
        Integer.parseInt(str);
        return true;
    } catch (Exception e) {
        return false;
    }
}

public static class Tester extends JFrame implements ActionListener {
    JTextField tf1, tf2;
    JButton okBtn;

    public Tester() {
        add(panel(), BorderLayout.CENTER);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 500);
        setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Tester();
            }
        });
    }

    public JPanel panel() {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        okBtn = new JButton("Ok");
        okBtn.addActionListener(this);
        tf1 = new JTextField(10);
        tf1.setName("tf1");
        tf2 = new JTextField(10);
        tf2.setName("tf2");
        tf1.setInputVerifier(new MyInputVerifier());
        tf2.setInputVerifier(new MyInputVerifier());
        panel.add(tf1);
//            panel.add(tf2);
        panel.add(okBtn);
        return panel;
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        MyInputVerifier inputVerifier = new MyInputVerifier();
        if (e.getSource() == okBtn) {
            if (inputVerifier.verify(tf2)) {
                JOptionPane.showMessageDialog(null, "True in tf2");
            } else JOptionPane.showMessageDialog(null, "False in tf2");
        }
    }
}
}

Output:

I enter 10

on joption pane: false in tf2
on console: in tf1
            in tf2

Solution

  • According doc the verify() method is called when the JTextField loose focus. In your code, tf1 loose focus when you click on okbtn. So the verify() method of tf1 is called and print in tf1.

    In the actionPerformed, you call explicitely the verify() method so in tf2 is printed. Since tf2 is empty (i.e. the line where you add it in the JPanel is commented): the JOptionPane display false in tf2

    I hope those explainations will help you to fix your code. You must understand that you don't need to call verify() yourself, it will be called automatically by the swing framework when the field loose the focus.