问题
I need such a numeric text field on JFrame that
- restricts the input by a number with two digits after decimal point
- lays out the number separating every three digits i.e. 1 234 567,89.
- 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 additionalFormatter
forNumber 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
withDocumentListener
added toJFormattedTextField
with plainNumber or DecimalFormatter
, without any restrictions, all workaround will be set in bothDocumentFilter
(designated for changes insideDocument
) withDocumentListener
(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