title: How to limit the number of digits in a JPasswordField in Java?
body: <p>I have my Java code working in Eclipse but I need to add a few functionnality.</p>
  
  <p>First, how to limit the number of digits that can be entered by the user ?
  Actually I have a JPasswordField that let a person enter a pin Code, and I would like this JPasswordField limited to 4 digits maximum. So how to stop the input as soon as 4 digits are entered ?</p>
  
  <p>Then, how can I play with the size of the JPassword box ? Is there a way to modify it just like a JTextField for example ? Because my line "p1.setPreferredSize(new Dimension(100, 25));" does not seem to really let me modify the size of the box.</p>
  
  <p><img src="https://i.stack.imgur.com/1SdD5.png" alt="enter image description here"></p>
  
  <p>As you can see, the JPassworldField box has a default size that I can not figure out how to modify easily.</p>
  
  <p>Here is my code :</p>
  
  <pre><code>package codePin;
  
  import java.io.*;
  import java.util.*;
  import java.util.concurrent.atomic.AtomicInteger;
  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 JPasswordField p1 = new JPasswordField(4);
      private JLabel label = new JLabel("Enter Pin: ");
      private JButton b = new JButton("OK");
  
      public Main() {
          this.setTitle("NEEDS");
          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();
          p1.setPreferredSize(new Dimension(100, 25)); //How to really modifiy this ?
  
          b.addActionListener(new BoutonListener());
  
          top.add(label);
          top.add(p1);
          p1.setEchoChar('*');
          top.add(b);
  
  
          this.setContentPane(top);
          this.setVisible(true);
      }
  
      class BoutonListener implements ActionListener {
          private final AtomicInteger nbTry = new AtomicInteger(0);
  
          @SuppressWarnings("deprecation")
          public void actionPerformed(ActionEvent e) {
              if (nbTry.get() &gt; 2) {
                  JOptionPane.showMessageDialog(null,
                          "Pin blocked due to 3 wrong tries");
                  return;
              }
              if (p1.getText().replaceAll("\u00A0", "").length() != 4) {
                  // System.out.println("Pin must be 4 digits");
                  JOptionPane.showMessageDialog(null, "Ping must be 4 digits");
                  return;
              }
              System.out.println("Checking...");
              SwingWorker&lt;Void, Void&gt; worker = new SwingWorker&lt;Void, Void&gt;() {
                  @Override
                  protected Void doInBackground() throws Exception {
                      boolean authenticated = false;
                      ArrayList&lt;Integer&gt; pins = new ArrayList&lt;Integer&gt;();
                      readPinsData(new File("bdd.txt"), pins);
                      String[] thePins = new String[pins.size()];
                      for (int i = 0; i &lt; thePins.length; i++) {
                          thePins[i] = pins.get(i).toString();
                      }
                      String passEntered = String.valueOf(p1);
                      for (String thePin : thePins) {
                          if (passEntered.equals(thePin)
                                  &amp;&amp; p1.getText().length() == 4) {
                              System.out.println(":)");
                              authenticated = true;
                              break;
                          }
                      }
                      if (!authenticated) {
                          System.out.println(":(");
                          nbTry.incrementAndGet();
                      }
                      return null;
                  }
              };
              worker.execute();
          }
  
      }
  
      // Accessing pins Bdd file
      static public boolean readPinsData(File dataFile, ArrayList&lt;Integer&gt; 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) {
          SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  new Main();
              }
          });
  
      }
  }
  </code></pre>
  
  <p>Any ideas ? Thanks.</p>
  
  <p>Florent</p>
  
  <p>Here is my code edited with nachokk's solution :</p>
  
  <pre><code>import java.io.*;
  import java.util.*;
  import java.util.concurrent.atomic.AtomicInteger;
  import javax.swing.*;
  import javax.swing.text.AttributeSet;
  import javax.swing.text.BadLocationException;
  import javax.swing.text.DocumentFilter;
  import javax.swing.text.PlainDocument;
  import java.awt.*;
  import java.awt.event.*;
  
  public class Main extends JFrame {
  
      private static final long serialVersionUID = 1L;
  
      private JPanel container = new JPanel();
      private JPasswordField p1 = new JPasswordField(4);
      private JLabel label = new JLabel("Enter Pin: ");
      private JButton b = new JButton("OK");
  
      public Main() {
          this.setTitle("NEEDS");
          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();
  
          PlainDocument document =(PlainDocument)p1.getDocument();
  
          b.addActionListener(new BoutonListener());
  
          top.add(label);
          top.add(p1);
          p1.setEchoChar('*');
          top.add(b);
  
  
          this.setContentPane(top);
          this.setVisible(true);
  
  
          document.setDocumentFilter(new DocumentFilter(){
  
              @Override
              public void replace(DocumentFilter.FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {
                  String string =fb.getDocument().getText(0, fb.getDocument().getLength())+text;
  
                  if(string.length() &lt;= 4)
                  super.replace(fb, offset, length, text, attrs); //To change body of generated methods, choose Tools | Templates.
              }
  
  
  
          });
          container.add(p1);
      }
  
      class BoutonListener implements ActionListener {
          private final AtomicInteger nbTry = new AtomicInteger(0);
  
          @SuppressWarnings("deprecation")
          public void actionPerformed(ActionEvent e) {
              if (nbTry.get() &gt; 2) {
                  JOptionPane.showMessageDialog(null,
                          "Pin blocked due to 3 wrong tries");
                  return;
              }
              if (p1.getText().replaceAll("\u00A0", "").length() != 4) {
                  // System.out.println("Pin must be 4 digits");
                  JOptionPane.showMessageDialog(null, "Ping must be 4 digits");
                  return;
              }
              System.out.println("Checking...");
              SwingWorker&lt;Void, Void&gt; worker = new SwingWorker&lt;Void, Void&gt;() {
                  @Override
                  protected Void doInBackground() throws Exception {
                      boolean authenticated = false;
                      ArrayList&lt;Integer&gt; pins = new ArrayList&lt;Integer&gt;();
                      readPinsData(new File("bdd.txt"), pins);
                      String[] thePins = new String[pins.size()];
                      for (int i = 0; i &lt; thePins.length; i++) {
                          thePins[i] = pins.get(i).toString();
                      }
                      String passEntered = String.valueOf(p1);
                      for (String thePin : thePins) {
                          if (passEntered.equals(thePin)
                                  &amp;&amp; p1.getText().length() == 4) {
                              System.out.println(":)");
                              authenticated = true;
                              break;
                          }
                      }
                      if (!authenticated) {
                          System.out.println(":(");
                          nbTry.incrementAndGet();
                      }
                      return null;
                  }
              };
              worker.execute();
          }
  
      }
  
      // Fonction permettant d'accéder/lire notre BDD de pins (fichier .txt)
      static public boolean readPinsData(File dataFile, ArrayList&lt;Integer&gt; 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) {
          SwingUtilities.invokeLater(new Runnable() {
              @Override
              public void run() {
                  new Main();
              }
          });
  
      }
  }
  </code></pre>