views:

243

answers:

4

I want to validate a jtextfield as user inputs a price of some item.

I have a perfectly working code which beeps and discard if user inputs some character that doesnt match the regular expression.(for regular expression "[0-9]+" it accepts any number of digits and beeps if a letter is given as input)

But the problem is I want to validate an input like "12500.00". Format should be any number of digits before decimal point and two digits after the decimal point. eg: ddd.dd

I tried the following regular expression. But the i doesnt allow user to input "." character. It allows user to input any number of digits but when "." key is pressed input is not accepted.

here is the regular expression I used. "[0-9]+ | [0-9]+. | [0-9]+.[0-9]{1} | [0-9]+.[0-9]{2}"

important: user input is validated character by character as the user inputs them to the jtextfield.

Here is the code

import java.awt.Toolkit;
import java.util.regex.Pattern;
import javax.swing.JComponent;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public abstract class ValidatedTextField extends PlainDocument {

private int max;
private String regExp;

public ValidatedTextField(int max, String regExp) {
    this.max = max;
    this.regExp = regExp;

}

@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
    Pattern DIGITS = Pattern.compile(regExp);
    // System.out.println(str);
    if (getLength() + str.length() > max) {
        str = str.substring(0, max - getLength());
        Toolkit.getDefaultToolkit().beep();
    }
    if (!DIGITS.matcher(str).matches() || str == null) {
        str = null;
        Toolkit.getDefaultToolkit().beep();
    }
    if (str != null && !passDependency(str)) {
        str = null;
        Toolkit.getDefaultToolkit().beep();
    }
    //str != null && DIGITS.matcher(str).matches

    super.insertString(offs, str, a);

}

public abstract boolean passDependency(String str);

public void shiftFocus(JComponent jc, boolean condition) {
    if (condition) {
        jc.requestFocusInWindow();
    }
}
}

Below is not the exact code but this is how I use it.

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

public class ValidateTest {
void makeFrame(){
    JFrame jf=new JFrame("Verifier Test");
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JTextField text = new JTextField();
    JLabel lbl=new JLabel("Price");

    text.setDocument(new ValidatedTextField(10, "[0-9]+") {

        @Override
        public boolean passDependency(String str) {
            return true;
        }
    });
    text.setPreferredSize(new Dimension(200, 30));
    lbl.setPreferredSize(new Dimension(60, 30));
    jf.getContentPane().add(text, BorderLayout.EAST);
    jf.getContentPane().add(lbl, BorderLayout.WEST);
    jf.pack();
    jf.setVisible(true);
    text.setVisible(true);
}
public static void main(String[] args) {
    new ValidateTest().makeFrame();
}
}
A: 
[0-9]+(?:\.[0-9]+)?

This matches (at least one digit) OPTIONALLY FOLLOWED BY (a single period followed by at least one digit).

Deniz Dogan
Wouldn't it be better to force exactly 2 digits (use {2} instead of +) after the decimal point (for $, £, € this is always true, and is stated in the question that the price will always have 2 decimal digits if specified).
Geoff
This doesnt accept "." character. Mind you characters are entered one by one. Text is validated at each character entryThis one works if whole string is matched at once i guess.(If my code is not erroneous, I posted my code)Thankyou for your concern
Niroshan
@Geoff: You're right.
Deniz Dogan
+1  A: 

Rather use NumberFormat#parse() and catch the ParseException.

BalusC
A: 

Check out RegExLib

Has about every regular expression you can think of somewhere in the library, and a tester to validate your own expressions. There are other regEx testers online as well, this is just one site I happen to like.

A simple search returned the following regEx: ^[$]?[0-9]*(.)?[0-9]?[0-9]?$

08Hawkeye
Thank you for the link. regex you provided doesnt do what I'm trying to do. it allows letters to be accepted as valied input.
Niroshan
+1  A: 

You are doing too much and a regex is not always the solution.

Use a JFormattedTextField with the amountFormat

See Sun's Java tutorial and demo

Mark
thank you very much using JFormattedTextField is much easier. saved me lot of time
Niroshan