Search code examples
javaeclipseswingjframejformattedtextfield

How to get length of a JFormattedTextField in Java?


I have a problem when I am trying to get the size of a JFormattedTextField. Actually I need the user to enter a simple pinCode, and then get the size of what he enters to loop on it right after it. If he entered 4 digits it's ok, or else he has to do it again. But when I run my project, I have an infinite loop with "Pin must be 4 digits"...

I already found this link, but it did not fix my problem.

Here's my code :

package codePin;

import java.io.*;
import java.text.NumberFormat;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Main extends JFrame {

    private static final long serialVersionUID = 1L;

    private JPanel container = new JPanel();
    private JFormattedTextField jtf = new JFormattedTextField(NumberFormat.getIntegerInstance());
    private JLabel label = new JLabel("Enter Pin: ");
    private JButton b = new JButton("OK");

    public Main() {
        this.setTitle("APP");
        this.setSize(300, 500);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setLocationRelativeTo(null);

        container.setBackground(Color.white);
        container.setLayout(new BorderLayout());
        JPanel top = new JPanel();
        Font police = new Font("Arial", Font.BOLD, 14);
        jtf.setFont(police);
        jtf.setPreferredSize(new Dimension(150, 30));
        jtf.setForeground(Color.BLUE);

        b.addActionListener(new BoutonListener());

        top.add(label);
        top.add(jtf);
        top.add(b); 

        this.setContentPane(top);
        this.setVisible(true);
    }

    class BoutonListener implements ActionListener {
        public void actionPerformed(ActionEvent e) {
            int nbTry = 0;
            boolean authenticated = false;

            do {
                do {

                    if (jtf.getText().length() != 4) { 
                        System.out.println("Pin must be 4 digits");
                    } else {
                        System.out.println("Checking...");
                    }

                    ArrayList<Integer> pins = new ArrayList<Integer>(); 
                    readPinsData(new File("bdd.txt"), pins);

                    String[] thePins = new String[pins.size()];
                    for (int i = 0; i < thePins.length; i++) {
                        thePins[i] = pins.get(i).toString();
                    }

                    String passEntered = String.valueOf(jtf);

                    for (int i = 0; i < thePins.length; i++) {
                        if (passEntered.equals(thePins[i]) && jtf.getText().length() == 4) {
                            System.out.println(":)");
                            authenticated = true;
                            break;
                        }
                    }
                } while (jtf.getText().length() != 4);
                if (!authenticated && jtf.getText().length() == 4) {
                    System.out.println(":(");
                    nbTry++;
                }
            } while (nbTry < 3 && !authenticated);
            //System.out.println("TEXT : jtf " + jtf.getText());

        }
    }

    // Function to read/access my pins database (file bdd.txt)
    static public boolean readPinsData(File dataFile, ArrayList<Integer> data) {
        boolean err = false;
        try {
            Scanner scanner = new Scanner(dataFile);
            String line;
            while (scanner.hasNext()) {
                line = scanner.nextLine();
                try {
                    data.add(Integer.parseInt(line));
                } catch (NumberFormatException e) {
                    e.printStackTrace();
                    err = true;
                }
            }
            scanner.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            err = true;
        }

        return err;
    }

    public static void main(String[] args) {

        Main fen = new Main();
    }
}

bdd.txt :

1111
1234
2222
3333
4444
5555
6666
7777
8888
9999

How can I do that ? Any ideas ?

Thanks, Florent.


Solution

  • None of the answers actually work. Short answer, you have to do the following check:

    if (jtf.getText().replaceAll("\u00A0","").length() != 4) {
        System.out.println("Pin must be 4 digits");
        JOptionPane.showMessageDialog(null,"Pin must be 4 digits");
        return;
    }
    

    Explanation: the unicode character \u0160 which is used in the NumberFormat is not a non-breaking space. After the \u there must be the hexadecimal representation of the character, that is \u00A0.

    Complete code:

    package codePin;
    import java.io.*;
    import java.text.NumberFormat;
    import java.util.*;
    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.*;
    import java.util.concurrent.atomic.AtomicInteger;
    
    
    public class Main extends JFrame {
    
        private static final long serialVersionUID = 1L;
    
        private JPanel container = new JPanel();
        private JFormattedTextField jtf = new JFormattedTextField(NumberFormat.getIntegerInstance());
        private JLabel label = new JLabel("Enter Pin: ");
        private JButton b = new JButton("OK");
    
        public Main() {
            this.setTitle("APP");
            this.setSize(300, 500);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setLocationRelativeTo(null);
    
            container.setBackground(Color.white);
            container.setLayout(new BorderLayout());
            JPanel top = new JPanel();
            Font police = new Font("Arial", Font.BOLD, 14);
            jtf.setFont(police);
            jtf.setPreferredSize(new Dimension(150, 30));
            jtf.setForeground(Color.BLUE);
    
            b.addActionListener(new BoutonListener());
    
            top.add(label);
            top.add(jtf);
            top.add(b);
    
            this.setContentPane(top);
            this.setVisible(true);
        }
    
        class BoutonListener implements ActionListener {
            private final AtomicInteger nbTry = new AtomicInteger(0);
            ArrayList<Integer> pins = readPinsData("bdd.txt");
            public void actionPerformed(ActionEvent e) {
                if (nbTry.get() > 2) {
                    JOptionPane.showMessageDialog(null, "Number of tries exceeded");
                    return;
                }
                final String passEntered=jtf.getText().replaceAll("\u00A0", "");
                if (passEntered.length() != 4) {
                    System.out.println("Pin must be 4 digits");
                    JOptionPane.showMessageDialog(null, "Ping must be 4 digits");
                    return;
                }
                System.out.println("Checking...");
                SwingWorker worker = new SwingWorker<Void, Void>() {
                    @Override
                    protected Void doInBackground() throws Exception {
                        boolean authenticated = false;
                        if (pins.contains(Integer.parseInt(passEntered))) {
                            System.out.println(":)");
                            authenticated = true;
                        }
    
                        if (!authenticated) {
                            System.out.println(":(");
                            nbTry.incrementAndGet();
                        }
                        return null;
                    }
                };
                worker.execute();
            }
    
    
        }
    
        // Function to read/access my pins database (file bdd.txt)
        static public ArrayList<Integer> readPinsData(String dataFile) {
            final ArrayList<Integer> data=new ArrayList<Integer>();
            try {
                BufferedReader reader = new BufferedReader(new FileReader(new File(dataFile)));
                String line;
                try {
                    while ((line = reader.readLine()) != null) {
                        try {
                            data.add(Integer.parseInt(line));
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                            System.err.printf("error parsing line '%s'\n", line);
                        }
                    }
                } finally {
                    reader.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
                System.err.println("error:"+e.getMessage());
            }
    
            return data;
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    Main fen = new Main();
                }
            });
    
        }
    }