1

I have a JTexTField that I would want a user to enter the name of a person. I have figured that the name should contain [a-zA-Z],. and space example Mr. Bill. I am using a DocumentFilter to validate user input.However, I cannot figure out how should I set this within my DocumentFilter.

Question: How should I modify my filter to achieve the above behavior?

Any suggestion on how to validate a person's name is accepted.

Here is my DocumentFilter:

public class NameValidator extends DocumentFilter{
@Override
public void insertString(DocumentFilter.FilterBypass fp, int offset,
        String string, AttributeSet aset) throws BadLocationException {
    int len = string.length();
    boolean isValidInteger = true;

    for (int i = 0; i < len; i++) {
        if (!Character.isLetter(string.charAt(i))) {
            isValidInteger = false;
            break;
        }
    }
    if (isValidInteger)
        super.insertString(fp, offset, string, aset);
    else {
        JOptionPane.showMessageDialog(null,
                "Please Valid Letters only.", "Invalid Input : ",
                JOptionPane.ERROR_MESSAGE);
        Toolkit.getDefaultToolkit().beep();
    }
}

@Override
public void replace(DocumentFilter.FilterBypass fp, int offset, int length,
        String string, AttributeSet aset) throws BadLocationException {
    int len = string.length();
    boolean isValidInteger = true;

    for (int i = 0; i < len; i++) {
        if (!Character.isLetter(string.charAt(i)) ) {
            isValidInteger = false;
            break;
        }
    }
    if (isValidInteger)
        super.replace(fp, offset, length, string, aset);
    else {
        JOptionPane.showMessageDialog(null,
                "Please Valid Letters only.", "Invalid Input : ",
                JOptionPane.ERROR_MESSAGE);
        Toolkit.getDefaultToolkit().beep();
     }
   }
 }

Here is my test class:

public class NameTest {

private JFrame frame;

public NameTest() {
    frame = new JFrame();
    initGui();
}

private void initGui() {

    frame.setSize(100, 100);
    frame.setVisible(true);
    frame.setLayout(new GridLayout(2, 1, 5, 5));
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextField name = new JTextField(15);
    ((AbstractDocument) name.getDocument())
            .setDocumentFilter(new NameValidator());
    frame.add(name);

}

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            NameTest nt = new NameTest();

         }
      });
    }
 }
CN1002
  • 1,115
  • 3
  • 20
  • 40
  • 1
    plus one, but I missing there quotation/punctuation marks, especially the single – mKorbel Apr 21 '15 at 15:54
  • @mKorbel Yes I was thinking of the single `'` but could not decide on it - example `O'Rourke`. Thanks for mentioning it. – CN1002 Apr 21 '15 at 16:03

2 Answers2

2

You could use a JFormattedTextField with a MaskFormatter. The MaskFormatter allows you to specify a String of valid characters.

MaskFormatter mf = new MaskFormatter( "***************" );
mf.setValidCharacters(" .abcABC");
JFormattedTextField ftf = new JFormattedTextField( mf );

Behind the scenes the formatted text field uses a DocumentFilter. Read the section from the Swing tutorial on How to Use Formatted Text Fields for more information and examples.

You can also try searching the forum/web for a regex DocumentFilter. This type of filter is generally reusable because you just need to specify the regex expression. For example: Trouble using regex in DocumentFilter for JTextField

Community
  • 1
  • 1
camickr
  • 321,443
  • 19
  • 166
  • 288
  • Will I be able to notify the user for invalid input beside using beeps? I would want to notify the user through a message dialog. – CN1002 Apr 21 '15 at 16:17
  • Well, suppose I have resorted to your implementation, how do I join my `regex` to validate for `[a-zA-Z]` and `\S`- white space? How does it look like when I put it in `setValidCharacters(" ....")`? -Thanks. – CN1002 Apr 21 '15 at 16:45
  • I suggested two different solutions. Ones is to use a regex in your DocumentFilter. I don't know anything about coding a valid regex so I can't help with the details. The second is to use a JFormattedTextField. In this case create a simple JFrame that just contains the JFormattedText field and test out the 3 lines of code I gave you to see how it works. – camickr Apr 21 '15 at 18:22
  • Well I tried your solution but it is allowing characters exactly in this format `abcABC` . After entering `B` you will not be able to enter `a,b,c and A`. Only that set of characters is allowed. – CN1002 Apr 22 '15 at 06:33
  • @Giovanrich, I'm not a mind reader. I don't see your code with the JFrame a JFormattedTextField. This is called a [SSCCE](http://sscce.org/). Without a proper `SSCCE` I can't offer any help. – camickr Apr 22 '15 at 15:26
  • Well, I do not see the reason to put another `SSCCE` whilst one is already there! You could have tested the three lines of code using the `SSCCE` I provided. – CN1002 Apr 23 '15 at 09:31
  • This is your question. You want the help, so you post the SSCCE that you want us to test. You made the statement that the code doesn't work, so you post the code that you tested. – camickr Apr 23 '15 at 15:44
  • Well, I have resorted to `DocumentFilter` with this regex `^[0-9\\_\\(\\)@!\"#%&*+,\\-:;<>=?\\[\\]\\^\\~\\{\\}\\|\\/]`. Thanks for looking into my question. I thought posting my SSCCE on this post would alter the original post. – CN1002 Apr 23 '15 at 15:56
0

The solution I found might be necessary for modifications to address all the validations I mentioned above. I have used DocumentFilter to eliminate \p{Punct}- except for . and ' from this set and [0 -9].

Here is the code that I used:

public class NameValidator extends DocumentFilter{
@Override
public void insertString(FilterBypass fb, int off
                    , String str, AttributeSet attr) 
                            throws BadLocationException 
{
    // remove 0-9 !"#$%&()*+,-/:;<=>?@[\]^_`{|}~
    //back space character is skipped here!
    fb.insertString(off, str.replaceAll("^[0-9\\_\\(\\)@!\"#%&*+,\\-:;<>=?\\[\\]\\^\\~\\{\\}\\|\\/]", ""), attr);
} 
@Override
public void replace(FilterBypass fb, int off
        , int len, String str, AttributeSet attr) 
                        throws BadLocationException 
{
    // remove 0-9 !"#$%&()*+,-/:;<=>?@[\]^_`{|}~
    fb.replace(off, len, str.replaceAll("^[0-9\\_\\(\\)@!\"#%&*+,\\-:;<>=?\\[\\]\\^\\~\\{\\}\\|\\/]", ""), attr);
       }

  }

Any modification are accepted to suit the stipulated validation in the original question.

CN1002
  • 1,115
  • 3
  • 20
  • 40