Search code examples
javadecimalformatjformattedtextfieldnumberformatter

The NumberFormatter function I made for JFormattedTextField, doesn't allow typing decimal numbers


In order to limit user's input to a specific numeric range I created this function:

public static final Locale GR=new Locale("el", "GR");

public static NumberFormatter getMyNumberFormatter(){
    NumberFormatter formatter = new NumberFormatter(NumberFormat.getInstance(GR));
    formatter.setValueClass(Double.class);
    formatter.setAllowsInvalid(false);
    formatter.setCommitsOnValidEdit(true);
    formatter.setMinimum(0.0);
    formatter.setMaximum(10000000.0);
    DecimalFormat df = (DecimalFormat)DecimalFormat.getInstance(GR);
    df.setGroupingUsed(true);
    formatter.setFormat(df);
    return formatter;
}

I applied this formatter to a JFormatedTextfield but it worked only on integer values. I want user to be able to type float numeric values from 0.0 to 10000000.0 but the current formatter allows only integers. Automatic grouping works perfect. Any suggestions?


Solution

  • As I remember JFormattedTextField is a pain to use.

    I assume that the DecimalFormat is not allowing numbers with just a decimal point, based on the following section of the javadoc:

    If you are going to allow the user to enter decimal values, you should either force the DecimalFormat to contain at least one decimal (#.0###), or allow the value to be invalid setAllowsInvalid(true). Otherwise users may not be able to input decimal values.

    You can also try to add

    df.setDecimalSeparatorAlwaysShown(true);
    

    One note: it is a bit confusing that the JFTF is created using one NumberFormat and later a new one is set. More straightforward (not tested):

    DecimalFormat df = (DecimalFormat)DecimalFormat.getInstance(GR);
    df.setGroupingUsed(true);
    df.setDecimalSeparatorAlwaysShown(true);
    NumberFormatter formatter = new NumberFormatter(df);
    ...
    

    or just

    NumberFormatter formatter = new NumberFormatter();
    ...
    formatter.setFormat(df);
    

    Suggestion (better IMO than using a JFTF):

    Extend a DocumentFilter and set it as filter of a new PlainDocument. Use a JTextField that uses that document.