Share this page 

Apply special filter to a JtextFieldTag(s): Swing


The following class will help a JTextField to filter numeric or alphanumeric characters.
import javax.swing.*;
import javax.swing.text.*;

 public class JTextFieldFilter extends PlainDocument {
   public static final String LOWERCASE  =
        "abcdefghijklmnopqrstuvwxyz";
   public static final String UPPERCASE  =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
   public static final String ALPHA   =
        LOWERCASE + UPPERCASE;
   public static final String NUMERIC =
        "0123456789";
   public static final String FLOAT =
        NUMERIC + ".";
   public static final String ALPHA_NUMERIC =
        ALPHA + NUMERIC;

   protected String acceptedChars = null;
   protected boolean negativeAccepted = false;

   public JTextFieldFilter() {
     this(ALPHA_NUMERIC);
     }
   public JTextFieldFilter(String acceptedchars) {
     acceptedChars = acceptedchars;
     }

   public void setNegativeAccepted(boolean negativeaccepted) {
     if (acceptedChars.equals(NUMERIC) ||
         acceptedChars.equals(FLOAT) ||
         acceptedChars.equals(ALPHA_NUMERIC)){
         negativeAccepted = negativeaccepted;
        acceptedChars += "-";
        }
      }

   public void insertString
      (int offset, String  str, AttributeSet attr)
         throws BadLocationException {
     if (str == null) return;

     if (acceptedChars.equals(UPPERCASE))
        str = str.toUpperCase();
     else if (acceptedChars.equals(LOWERCASE))
        str = str.toLowerCase();

     for (int i=0; i < str.length(); i++) {
       if (acceptedChars.indexOf(str.valueOf(str.charAt(i))) == -1)
         return;
       }

     if (acceptedChars.equals(FLOAT) ||
        (acceptedChars.equals(FLOAT + "-") && negativeAccepted)) {
        if (str.indexOf(".") != -1) {
           if (getText(0, getLength()).indexOf(".") != -1) {
              return;
              }
           }
        }

     if (negativeAccepted && str.indexOf("-") != -1) {
        if (str.indexOf("-") != 0 || offset != 0 ) {
           return;
           }
        }

     super.insertString(offset, str, attr);
   }
}

import java.awt.*;
import javax.swing.*;

  public class TESTJTextFieldFilter extends JApplet{
    JTextField tf1,tf1b,tf1c,tf2,tf3;
    JLabel l1,l1b,l1c,l2,l3;

    public void init() {
      getContentPane().setLayout(new FlowLayout());
      //
      l1 = new JLabel("only numerics");
      tf1 = new JTextField(10);
      getContentPane().add(l1);
      getContentPane().add(tf1);
      tf1.setDocument
         (new JTextFieldFilter(JTextFieldFilter.NUMERIC));

      //
      l1b = new JLabel("only float");
      tf1b = new JTextField(10);
      getContentPane().add(l1b);
      getContentPane().add(tf1b);
      tf1b.setDocument
         (new JTextFieldFilter(JTextFieldFilter.FLOAT));

      //
      l1c = new JLabel("only float(can be negative)");
      tf1c = new JTextField(10);
      getContentPane().add(l1c);
      getContentPane().add(tf1c);
      JTextFieldFilter jtff = new JTextFieldFilter(JTextFieldFilter.FLOAT);
      jtff.setNegativeAccepted(true);
      tf1c.setDocument(jtff);

      //
      l2 = new JLabel("only uppercase");
      tf2 = new JTextField(10);
      getContentPane().add(l2);
      getContentPane().add(tf2);
      tf2.setDocument
         (new JTextFieldFilter(JTextFieldFilter.UPPERCASE));

      //
      l3 = new JLabel("only 'abc123%$'");
      tf3 = new JTextField(10);
      getContentPane().add(l3);
      getContentPane().add(tf3);
      tf3.setDocument
         (new JTextFieldFilter("abc123%$"));
      }
}

With JDK.14, you have the JFormattedTextField class. You can provide an input mask like (###) ###-#### for a telephone number, and it will not accept any input that doesn't follow that format.

import java.awt.Container;
import javax.swing.*;
import javax.swing.text.*;
import java.text.ParseException;

public class FormattedSample {
  public static void main (String args[]) throws ParseException {
    JFrame f = new JFrame("JFormattedTextField Sample");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container content = f.getContentPane();
    content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));
    // canadian Social Security Number
    MaskFormatter mf1 = new MaskFormatter("###-###-###");
    mf1.setPlaceholderCharacter('_');
    JFormattedTextField ftf1 = new JFormattedTextField(mf1);
    content.add(ftf1);
    // telephone number
    MaskFormatter mf2 = new MaskFormatter("(###) ###-####");
    JFormattedTextField ftf2 = new JFormattedTextField(mf2);
    content.add(ftf2);
    f.setSize(300, 100);
    f.setVisible(true);
  }
}
It's also possible to provide simple validation. For example, specify a field to accept only numeric with a minimum and a maximum value. If the input is not valid then a warning beep is produced.
import java.awt.Container;
import javax.swing.*;
import javax.swing.text.*;
import java.text.ParseException;

public class FormattedSample {
  public static void main (String args[]) throws ParseException {
    JFrame f = new JFrame("JFormattedTextField Sample");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    Container content = f.getContentPane();
    content.setLayout(new BoxLayout(content, BoxLayout.PAGE_AXIS));

    NumberFormatter nf = new NumberFormatter();
    nf.setValueClass(Integer.class);
    nf.setMinimum(new Integer(0));
    nf.setMaximum(new Integer(100));

    JFormattedTextField field = new JFormattedTextField(nf);
    field.setBorder(BorderFactory.createLineBorder(Color.black));
    content.add(field);

    f.setSize(300, 100);
    f.pack();
    f.setVisible(true);
  }
}