1

I am trying to validate text field such that it accepts float or double values like .25, 0.2, 111.25
It should not accepts values like ...25, 0.2.2. etc

  • Duplicate. http://stackoverflow.com/questions/9341695/regex-to-match-any-number-real-rational-along-with-signs – christopher Apr 08 '13 at 09:51
  • The same as for numeric values (shown [here](http://stackoverflow.com/a/13424140/1076463)), but using another `java.text.Format` – Robin Apr 08 '13 at 10:06
  • possible duplicate of [Is there any way to accept only numeric values in a JTextField?](http://stackoverflow.com/questions/1313390/is-there-any-way-to-accept-only-numeric-values-in-a-jtextfield) – Robin Apr 08 '13 at 10:07
  • but for validation of form i am not getting it, using jtextfield only. – Chaitanya Gadam Apr 08 '13 at 10:19

3 Answers3

4

JFormattedTextField example

enter image description here

import java.awt.*;
import java.awt.font.TextAttribute;
import java.math.*;
import java.text.*;
import java.util.Map;
import javax.swing.*;
import javax.swing.JFormattedTextField.*;
import javax.swing.event.*;
import javax.swing.text.InternationalFormatter;

public class DocumentListenerAdapter {

    public static void main(String args[]) {
        JFrame frame = new JFrame("AbstractTextField Test");
        final JFormattedTextField textField1 = new JFormattedTextField(new Float(10.01));
        textField1.setFormatterFactory(new AbstractFormatterFactory() {

            @Override
            public AbstractFormatter getFormatter(JFormattedTextField tf) {
                NumberFormat format = DecimalFormat.getInstance();
                format.setMinimumFractionDigits(2);
                format.setMaximumFractionDigits(2);
                format.setRoundingMode(RoundingMode.HALF_UP);
                InternationalFormatter formatter = new InternationalFormatter(format);
                formatter.setAllowsInvalid(false);
                formatter.setMinimum(0.0);
                formatter.setMaximum(1000.00);
                return formatter;
            }
        });
        final Map attributes = (new Font("Serif", Font.BOLD, 16)).getAttributes();
        attributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
        final JFormattedTextField textField2 = new JFormattedTextField(new Float(10.01));
        textField2.setFormatterFactory(new AbstractFormatterFactory() {

            @Override
            public AbstractFormatter getFormatter(JFormattedTextField tf) {
                NumberFormat format = DecimalFormat.getInstance();
                format.setMinimumFractionDigits(2);
                format.setMaximumFractionDigits(2);
                format.setRoundingMode(RoundingMode.HALF_UP);
                InternationalFormatter formatter = new InternationalFormatter(format);
                formatter.setAllowsInvalid(false);
                //formatter.setMinimum(0.0);
                //formatter.setMaximum(1000.00);
                return formatter;
            }
        });
        textField2.getDocument().addDocumentListener(new DocumentListener() {

            @Override
            public void changedUpdate(DocumentEvent documentEvent) {
                printIt(documentEvent);
            }

            @Override
            public void insertUpdate(DocumentEvent documentEvent) {
                printIt(documentEvent);
            }

            @Override
            public void removeUpdate(DocumentEvent documentEvent) {
                printIt(documentEvent);
            }

            private void printIt(DocumentEvent documentEvent) {
                DocumentEvent.EventType type = documentEvent.getType();
                double t1a1 = (((Number) textField2.getValue()).doubleValue());
                if (t1a1 > 1000) {
                    Runnable doRun = new Runnable() {

                        @Override
                        public void run() {
                            textField2.setFont(new Font(attributes));
                            textField2.setForeground(Color.red);
                        }
                    };
                    SwingUtilities.invokeLater(doRun);
                } else {
                    Runnable doRun = new Runnable() {

                        @Override
                        public void run() {
                            textField2.setFont(new Font("Serif", Font.BOLD, 16));
                            textField2.setForeground(Color.black);
                        }
                    };
                    SwingUtilities.invokeLater(doRun);
                }
            }
        });
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(textField1, BorderLayout.NORTH);
        frame.add(textField2, BorderLayout.SOUTH);
        frame.setVisible(true);
        frame.pack();
    }

    private DocumentListenerAdapter() {
    }
}
mKorbel
  • 109,525
  • 20
  • 134
  • 319
3

-?(\d*\.)?\d+([eE][+\-]?\d+)?|[nN]a[nN]|[iI]nf(inity)? is the regex I usually use for parsing doubles.

If you don't want infinities and NaNs,

-?(\d*\.)?\d+([eE][+\-]?\d+)?

If you also don't want exponential notation,

-?(\d*\.)?\d+

And don't forget to escape backslashes if you need to.

Patashu
  • 21,443
  • 3
  • 45
  • 53
  • @Chaitanya Gadam I am testing the regex in the python interpreter and it works fine for me. – Patashu Apr 08 '13 at 10:04
  • do you have any idea doing this in java swing? – Chaitanya Gadam Apr 08 '13 at 10:07
  • @Chaitanya Gadam Use a debugger. Is the string that matches is called on exactly what you expected? Simplify the problem. Write a test case that tries the regex on known strings. Does it work when you expect and not when you don't? Why or why not? – Patashu Apr 08 '13 at 10:08
3

Create a class that extends PlainDocument and then set the jtextfield setDocument() to your new document class.

import java.awt.Toolkit;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public class DoubleDocument extends PlainDocument {

    int size;

    public DoubleDocument(int size) {
        this.size = size;
    }

    @Override
    public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
        if(str == null){
            return;
        }

        if(getLength() + str.length() > size){
            Toolkit.getDefaultToolkit().beep();
            return;
        }

        boolean isValid = true;
        for(int i = 0; i < str.length(); i++){
            if(!Character.isDigit(str.charAt(i))){
                if(str.charAt(i) != '.'){
                    isValid = false;
                    break;
                } else {
                    if(this.getText(0, this.getLength()).contains(".")){
                        isValid = false;
                        break;
                    }
                }
            }
        }

        if(isValid){
            super.insertString(offs, str, a);
        } else {
            Toolkit.getDefaultToolkit().beep();
        }
    }

}

then implement like this.

txtLoanAmount.setDocument(new DoubleDocument(12));

you can choose to remove the size in the DoubleDocument class if you don't care about the length of the field. Hope this helps.