JFormattedTextField with strict parsing format

Since someone pointed out my other question ( NumberFormat parse not strict enough ) as a duplicate by mistake and did not delete the duplicate shortcut, although I indicated that it was different, I will send the question again along with my solution. Maybe this is useful to someone. Here we go:

I have a JFormattedTextField with NumberFormat with Locale.US. Thus, the decimal separator is a period, and the grouping separator is a comma.

Now I type the string "1.23" in this text box and move the focus to another component. I would expect the string to disappear (for example, when I type "a" instead of "1.23"), because this is clearly not a valid representation of the number when using Locale.US. But instead, the text in the text box changes to "123".

This is because the NumberFormat used is not strict on parsing and just ignores the comma.

Question:. How can I tell NumberFormat to throw a ParseException in this case, so that the text field is empty after moving the focus to another component?

Test code:

JDialog dialog = new JDialog(); JPanel panel = new JPanel(new BorderLayout()); dialog.getContentPane().add(panel); NumberFormat nf = NumberFormat.getInstance(Locale.US); JFormattedTextField textField = new JFormattedTextField(nf); textField.setText("1,23"); panel.add(textField, BorderLayout.CENTER); panel.add(new JButton("focus"), BorderLayout.EAST); dialog.pack(); dialog.setVisible(true); 

Move the focus from the text box to the button, and the text will change to "123".

+1
java swing number-formatting jformattedtextfield
source share
1 answer

Here is my solution:

First, I create a custom DecimalFormat with strict parsing. Only numbers and not more than one decimal point are allowed.

  public class StrictDecimalFormat extends DecimalFormat { private static final Pattern NUMBER_PATTERN = Pattern.compile("^\\d*[.]?\\d*$"); public Number parse(String text, ParsePosition pos) { Matcher matcher = NUMBER_PATTERN.matcher(text); if (matcher.matches()) { return super.parse(text, pos); } return null; } } 

Now I am using this decimal format for my JFormattedTextField. Since the locale itself cannot be set in decimal, I have to create the appropriate DecimalFormatSymbols and set it.

  DecimalFormatSymbols decimalFormatSymbols = new DecimalFormatSymbols(Locale.US); DecimalFormat strictFormat = new StrictDecimalFormat(); strictFormat.setDecimalFormatSymbols(decimalFormatSymbols); JDialog dialog = new JDialog(); JPanel panel = new JPanel(new BorderLayout()); dialog.getContentPane().add(panel); JFormattedTextField textField = new JFormattedTextField(strictFormat); textField.setText("1,23"); panel.add(textField, BorderLayout.CENTER); panel.add(new JButton("focus"), BorderLayout.EAST); dialog.pack(); dialog.setVisible(true); 
+1
source share

All Articles