Frage

In my application I want to input numbers (amounts) to a specific limit, and hence have used JFormattedTextField. Limit like "12345678.99" i.e. 8 digits before "." and 2 after "." or so on. This is my implementation code, but it doesn't result as expected.

    startBalTxt.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(new javax.swing.text.NumberFormatter(new java.text.DecimalFormat("########.##"))));
    startBalTxt.setText(resourceMap.getString("startBalTxt.text")); // NOI18N
    startBalTxt.setFont(Utility.getTextFont());
    startBalTxt.setName("startBalTxt"); // NOI18N

  INPUT                RESULT  
"12345678905.99"   => "12345678906"      ==> Should give "12345678.99" or "12345679.99"
"12345678.555"     => "12345678.56"      ==> CORRECT
"1234567890123456" => "1234567890123456" ==> Absolutely wrong in all aspects

Where am I going wrong ? And how to make this working as I am expecting it.

UPDATIONS AS PER SUGGESTED by StanislavL :

    numberFormat = (DecimalFormat) DecimalFormat.getNumberInstance();
    numberFormat.setMaximumFractionDigits(2);
    numberFormat.setMaximumIntegerDigits(8);
    numberFormat.setMinimumFractionDigits(0);
    numberFormat.setMinimumIntegerDigits(2);

    nfr = new NumberFormatter(numberFormat);

    initComponents();
    myParent = parent;
    this.startBalTxt.setFormatterFactory(new javax.swing.text.DefaultFormatterFactory(nfr));

    Results ->  4562147896.45  == > 62,147,896.45

Its obeying the limit that's true, but its eliminating previous numbers instead of later. I mean in 4562147896.45 instead of "45" "96" shouldn't be eliminated.

War es hilfreich?

Lösung

even JFormattedTextField implements DecimalFormat and NumberFormat, better would be use DocumentListener,

1) its not good jumping betweens Big Figures by using DecimalFormat or NumberFormat simple User-non-Acceptable by implements setMinimum() and setMaximum()

2) JTextComponents by default implements insert the text, then any workaround is so User-non-Acceptable by implementsJFormattedTextField with DecimalFormat orNumberFormat by implements setMinimum() and setMaximum()

3) its very confortable je use DocumentListener allows add any amount, but with highlighting out-off range

4) or use JSpinner with SpinnerNumberModel, there is posible to set Formatter as for Number Instance

example for InternationalFormatter and DocumentListener together

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() {
    }
}

Andere Tipps

Pass DecimalFormat to the JFormattedTextField constructor. It has following methods

setMaximumIntegerDigits
setMinimumIntegerDigits
setMaximumFractionDigits
setMinimumFractionDigits
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top