javaregexswingdocumentfilter

How to restrict more than two digits after a dot using Regex and DocumentFilter?


I am trying to make some JTextFields to validate only double numbers like currency ($xxx.xx), I wrote a class using DocumentFilter to validate the pattern and the size of characters, but what I can not achieve is that the user can type more than one dot.

Here is an example of my code:

private class LimitCharactersFilter extends DocumentFilter {

    private int limit;
    private Pattern regex = Pattern.compile( "\\d*(\\.\\d{0,2})?");
    private Matcher matcher;

    public LimitCharactersFilter(int limit) {           
        this.limit = limit;
    }

    @Override
    public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr)
            throws BadLocationException {
        String fullText = fb.getDocument().getText(0, fb.getDocument().getLength()) + string;
        matcher = regex.matcher(fullText);
        if((fullText.length()) <= limit && matcher.matches()){
            fb.insertString(offset, string, attr);
        }else{
            Toolkit.getDefaultToolkit().beep();
        }
    }

    @Override
    public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs)
            throws BadLocationException {
        String fullText = fb.getDocument().getText(0, fb.getDocument().getLength()) + text;
        matcher = regex.matcher(fullText);
        matcher = regex.matcher(text);
        if((fullText.length()) <= limit && matcher.matches()){
            fb.replace(offset,length, text, attrs);
        }else{
            Toolkit.getDefaultToolkit().beep();
        }
    }
}

And here is a picture of how the interface looks: Interface Screenshot

Validate the limit of characters works great, but I want to restrict the user to enter more than two digits if there's already a dot.

Hope someone can help me with this.


Solution

  • To allow the dot to be entered when typing a float number, you can use

    \\d*\\.?\\d{0,2}
    

    Note that here,

    Please also consider using VGR's suggestion:

    new JFormattedTextField(NumberFormat.getCurrencyInstance());
    

    This will create a text field that allows currency as input.