How to define a formatted text field in Swing so that the format restrictions are applied as you type?

家住魔仙堡 提交于 2019-12-24 17:12:05

问题


I need such a numeric text field on JFrame that

  1. restricts the input by a number with two digits after decimal point
  2. lays out the number separating every three digits i.e. 1 234 567,89.
  3. the number is displayed in correct format right away during typing

I tried using JFormattedTextField:

    NumberFormat nf = NumberFormat.getNumberInstance();
    nf.setMaximumFractionDigits(2);
    NumberFormatter numFormater = new NumberFormatter(nf);
    field1 = new javax.swing.JFormattedTextField(numFormater);

However, format restricitions apply only when focus leaves the component, which is a problem. I want user to be able to type only digits and delimeter in the field, and a space delimeter be placed right after each 3-d digit is entered in the field.

I can do this in C# just by specifing properties of the field. What is a clean way to do this in Swing? Thank you.


回答1:


  • one of ways is usage of InternationalFormatter which is additional Formatter for Number or DecimalFormatter

  • every restriction in JFormattedTextField has side effects for users input, e.g. Caret, Selection, etc.

  • proper of ways could be usage of combinations DocumentFilter with DocumentListener added to JFormattedTextField with plain Number or DecimalFormatter, without any restrictions, all workaround will be set in both DocumentFilter(designated for changes inside Document) with DocumentListener(outside of Document)

for example mentioned InternationalFormatter

import java.awt.*;
import java.math.*;
import java.text.*;
import javax.swing.*;
import javax.swing.JFormattedTextField.AbstractFormatter;
import javax.swing.JFormattedTextField.AbstractFormatterFactory;
import javax.swing.text.InternationalFormatter;

public class DocumentListenerAdapter {

    public DocumentListenerAdapter() {
        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;
            }
        });
        NumberFormat numberFormat = NumberFormat.getNumberInstance();
        numberFormat.setMaximumFractionDigits(2);
        numberFormat.setMaximumFractionDigits(2);
        numberFormat.setRoundingMode(RoundingMode.HALF_UP);
        final JFormattedTextField textField2 = new JFormattedTextField(numberFormat);
        textField2.setValue(new Float(10.01));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(textField1, BorderLayout.NORTH);
        frame.add(textField2, BorderLayout.SOUTH);
        frame.setVisible(true);
        frame.pack();
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new DocumentListenerAdapter();
            }
        });
    }
}

for example JSpinner (editor is JFormattedTextField) with very simple DocumentFilter




回答2:


How about adding a KeyListener to the field and reformatting whenever a key is typed?



来源:https://stackoverflow.com/questions/20142407/how-to-define-a-formatted-text-field-in-swing-so-that-the-format-restrictions-ar

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!