Hey Guys,

So I have a JTextfield in the cells of 1 of the columns in my JTable

I want to allow only numbers and up to one dot/period. Doesant need to contain a period.
The persiod can be anywhere except at the end of the number.

1 ok
.1 ok
1.1 ok
1.1.1 not ok

  1. not ok

This is my expression in my code

Currantly it allows only numbers which is good,
but it doesant allow any periods, :(...

 private JTextField createTextField() {
        JTextField field = new JTextField();
        ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
            @Override
            public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
                    throws BadLocationException {

                fb.insertString(off, str.replaceAll("(?<=^| )\\D+(\\.\\D+)?(?=$| )|(?<=^| )\\.\\D+(?=$| )", ""), attr);  // remove non-digits
            }
            @Override
            public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
                    throws BadLocationException {
                fb.replace(off, len, str.replaceAll("(?<=^| )\\D+(\\.\\D+)?(?=$| )|(?<=^| )\\.\\D+(?=$| )", ""), attr);  // remove non-digits
            }
        });
        return field;
    }

Any Help will be greatly appreciated (Y) :)

Thanks guys,

Recommended Answers

All 23 Replies

What you want is

0 or more digits ^[0-9]* followed by
0 or 1 decimals \.? followed by
1 or more digits [0-9]+$

which gives you

^[0-9]*\.?[0-9]+?$

Coincidentally, I had just posted a regular expression tester vb.Net project which is what I used to build the above expression.

commented: +1 coinkidink. +15

So this doesant allow numbers only letters.... and more than 1 decimal point....??

I dont know, I put it in like this maybe im doing it wrong.

 private JTextField createTextField() {
        JTextField field = new JTextField();
        ((AbstractDocument) field.getDocument()).setDocumentFilter(new DocumentFilter() {
            @Override
            public void insertString(FilterBypass fb, int off, String str, AttributeSet attr)
                    throws BadLocationException {

                fb.insertString(off, str.replaceAll("^[0-9]*\\.?[0-9]+?$", ""), attr);  // remove non-digits
            }
            @Override
            public void replace(FilterBypass fb, int off, int len, String str, AttributeSet attr)
                    throws BadLocationException {
                fb.replace(off, len, str.replaceAll("^[0-9]*\\.?[0-9]+?$", ""), attr);  // remove non-digits
            }
        });
        return field;
    }

So this doesant allow numbers only letters.... and more than 1 decimal point....??

How did you get that from what I posted? What I gave you evaluates as

2018-07-16_173811.jpg

I see you entered the pattern as ^[0-9]*\\.?[0-9]+?$. I don't use java so I don't know the syntax but is seems to me that \\. will match a backslash followed by any character. Shouldn't that just be one backslash?

commented: Slick graphic. Nice. +0
commented: nice graphics agree lol, but... +3

If I take away 1 of the backslashes, Then I get an error,
"Illegal escape character"

I need them both to not get any errors,

In a java string literal the backslash is an escape char, so to enter an actual backslash you need to code two backslashes

I guess java doesn't have a raw string capability like python. I used Regexper to generate the graphic.

commented: No, it doesn't. :( +15

Anyone else have any input?

Tried a bunch of differant solutions, None of them work :(

Thank you very much so far.

Keep in mind if the above wouldve worked, it wouldent of allowed a period/dot at the begginging of the string,
I do need this.

I can't test it in Java but it works the way you want in vbScript and vb.Net. My pattern clearly states "zero or more digits before a decimal point".

@all. I tried to use some online Java regex tools and it appears something is indeed different about Java. (duh?)

I love reguler expressions till somthing like this happens :(

I tried to account for differing dialogs by using [0-9] (which is standard) as opposed to \d (which is not) but, oh well.

Any other Idea's Reverand??

You may just be able to save me :)

When I use a regular expression(rarely) I use a Regex class. Sample code in C# and VB.
Don't know if something similar exists in Java. But I doubt if no one has developed a library for it.

Since I do not use java and can't test it locally, I suggest that you work on just the regular expression and test it in one of the free, online java regex testers available. Google java regular expression tester and pick one of the several available.

I'm Still having trouble figuring this out and for the life of me cant do it,

Anyone have anything?

I want to allow only numbers and up to one dot/period. Doesant need to contain a period.

I gave you the regex that does what you want. Presumably your problem is translating it into a string that will work in java for which I am unable to help you. Is there a java person out there who can give it a try?

Perhaps this can help.

Hi guys, mind if I join in?

I tried ^[0-9]*\.?[0-9]+?$ in Java - just needed to double up the backslash for a Java literal. Works OK for me.

Maybe the problem is in how the regex is being used. The replace method in the earliest code doesn't use regexs. The replaceAll in the later code does use a regex, but the way it works is to replace any string that matches the regex. So the code will replace a valid input string with an empty string, but leave invalid strings alone. This is not what the comment suggests the OP wants.

You can simply test a string for being valid with Pattern.matches like this:

        String s = "1.2"; // or other test cases
        String r = "^[0-9]*\\.?[0-9]+?$";
        System.out.println(s + " is " + Pattern.matches(r, s));

but it seems maybe OP wants to reject any chars that cause the string to be invalid. I'm not sure thats achievable. Eg for "1.2.3" which char would you reject?
I personally think that's an undesirable approach anyway; I would probably do this in 2 stages - (1) block anything not a number or period from being entered, then (2) parse the string fully when user presses enter - rejecting bad input with a useful message and and allowing the user to fix it

ps: Why not use a JFormattedTextField with a NumberFormatter because what you describe looks a lot like a decimal number

I have an above feeling that mve code is correct, it is just working backwords, im not sure, everything online does the opposit that I want, They say it removes letters, it allows numbers and not letters....

Just some background, This is filtering a JTextfield as a user is typing inside of a jtable.

If it's being used interactively (as in while the chars are being typed) then it can't work. For example, to enter the number 123.45, each of the first three digits would be allowed by the pattern. However, as soon as the . is entered it would be flagged as invalid because a number cannot end with a .. The user would have to enter 12345 and then backspace twice to enter the .. I think the OP has to describe, in detail, how he/she wants the input process to work. And I emphasize "in detail". As in "what do you want to happen at each keypress?" If it is impossible to do this then it is likely impossible to code it.

IMO, I don't see why 123. should be invalid when 123.0 is valid.

mve code is correct, it is just working backwords,

??? This is what we call "denial" and it's never going to help. It's not correct because it doesn't do what you want, and a root cause of that is because you are trying to do the wrong thing in the first place.

RJ is right. Full validation on a keystroke by keystroke basis is horribly confusing for the user. Please just filter to ignore all non numerics and periods, then do the full validation when the user presses enter, or if you can't do that, then when the field loses focus.

... but I still don't understand why you don't just use the Swing built-in classes, eg

 JFormattedTextField field = 
      new JFormattedTextField(NumberFormat.getNumberInstance());
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.