Reputation: 155
I have a problem with formatting a currency decimal number in TextField
. I set the TextFormatter
with a class DecimalFormatter
that extend a StringConverter
which converts a BigDecimal
to String
and vice-versa.
When I should change the value, if delete all the data and insert a new completed value it works, but if I have to add/change a part of value e.g. 13.00 in 13.10 the change is not applied and re-proposes the old value 13.00.
How can I solve it?
Thank you
public class DecimalFormatter extends StringConverter<BigDecimal> {
private NumberFormat numberFormat;
....
@Override
public String toString(BigDecimal value) {
if ( value == null )
value = new BigDecimal();
return numberFormat.format(value.doubleValue());
}
@Override
public BigDecimal fromString(String value) {
return new BigDecimal(value);
}
}
....
tfDecimal.setTextFormatter(new DecimalFormatter());
Upvotes: 1
Views: 1086
Reputation: 155
My intention was to manage amounts with decimals separated by a comma in a textfield. I added a filter to allow only double amounts. The complete code:
public class DecimalFormatter extends StringConverter {
private final NumberFormat numberFormat = NumberFormat.getNumberInstance(Locale.ITALY);
public DecimalFormatter(int fractionsLenght) {
numberFormat.setMaximumFractionDigits(fractionsLenght);
numberFormat.setMinimumFractionDigits(fractionsLenght);
}
public DecimalFormatter() {
numberFormat.setMaximumFractionDigits(2);
numberFormat.setMinimumFractionDigits(2);
}
@Override
public String toString(BigDecimal value) {
if ( value == null )
value = new BigDecimal(0);
return numberFormat.format(value.doubleValue());
}
@Override
public Decimal fromString(String value) {
value = value.replaceAll(",", ".");
return new BigDecimal(value);
}
}
public class DecimalFilter implements UnaryOperator {
private static final char DECIMAL_SEPARATOR = DecimalFormatSymbols.getInstance().getDecimalSeparator();
private Pattern DIGIT_PATTERN;
public DecimalFilter() {
DIGIT_PATTERN = Pattern.compile("-?\\d*(\\" + DECIMAL_SEPARATOR + "\\d{0,2})?");
}
public DecimalFilter(int fractionsLenght) {
DIGIT_PATTERN = Pattern.compile("-?\\d*(\\" + DECIMAL_SEPARATOR + "\\d{0," + fractionsLenght + "})?");
}
@Override
public Change apply(TextFormatter.Change aT) {
return DIGIT_PATTERN.matcher(aT.getText()).matches() ? aT : null;
}
}
tfDecimalValue.setTextFormatter(
new TextFormatter(new DecimalFormatter(), new BigDecimal(0), new DecimalFilter()));
Upvotes: 1