Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
setPropertyDataSource's formatter does not work for custom component
Hello,
I'm working on a Vaadin 6 project and I have implemented a new custom component (that extends CustomComponent and implements Field). The custom component has a textfield (the actual 'bound' field) and a label (for information next to the textfield). The problem arrives when I call setPropertyDataSource with a specific decimal formatter. It just ignores the formatting. If I just call the same method on a plain textfield, then I get the formatting I want. Here's my custom component:
CustomComponent implementation class:
public class TextFieldWithCalculatedLabelCustomComponent extends CustomComponent implements Field {
private TextField boundField = new TextField();
private Label label = new Label();
public TextFieldWithCalculatedLabelCustomComponent(final GtmxAttrbts gtmxAttrbts, String labelCaption) {
HorizontalLayout layout = new HorizontalLayout();
layout.setSpacing(true);
layout.addComponent(boundField);
boundField.setImmediate(true);
boundField.setNullRepresentation("");
boundField.setNullSettingAllowed(true);
label.setCaption(labelCaption);
layout.addComponent(label);
layout.setComponentAlignment(label, "b");
setCompositionRoot(layout);
}
public abstract void calculateLabel();
public TextField getBoundField() {
return boundField;
}
public Label getLabel() {
return label;
}
public String getRequiredError() {
return boundField.getRequiredError();
}
public boolean isRequired() {
return boundField.isRequired();
}
public void setRequired(boolean required) {
boundField.setRequired(required);
}
public void setReadOnly(boolean readOnly) {
boundField.setReadOnly(readOnly);
}
public boolean isReadOnly() {
return boundField.isReadOnly();
}
public void setRequiredError(String requiredMessage) {
boundField.setRequiredError(requiredMessage);
}
public boolean isInvalidCommitted() {
return boundField.isInvalidCommitted();
}
public void setInvalidCommitted(boolean isCommitted) {
boundField.setInvalidCommitted(isCommitted);
}
public void commit() throws SourceException, InvalidValueException {
boundField.commit();
}
public void discard() throws SourceException {
boundField.discard();
}
public boolean isModified() {
return boundField.isModified();
}
public boolean isReadThrough() {
return boundField.isReadThrough();
}
public boolean isWriteThrough() {
return boundField.isWriteThrough();
}
public void setReadThrough(boolean readThrough) throws SourceException {
boundField.setReadThrough(readThrough);
}
public void setWriteThrough(boolean writeThrough) throws SourceException, InvalidValueException {
boundField.setWriteThrough(writeThrough);
}
public void addValidator(Validator validator) {
boundField.addValidator(validator);
}
public Collection<Validator> getValidators() {
return boundField.getValidators();
}
public boolean isInvalidAllowed() {
return boundField.isInvalidAllowed();
}
public boolean isValid() {
return boundField.isValid();
}
public void removeValidator(Validator validator) {
boundField.removeValidator(validator);
}
public void setInvalidAllowed(boolean invalidValueAllowed) throws UnsupportedOperationException {
boundField.setInvalidAllowed(invalidValueAllowed);
}
public void validate() throws InvalidValueException {
boundField.validate();
}
public Class<?> getType() {
return boundField.getType();
}
public void setValue(Object newValue) throws ReadOnlyException, ConversionException {
boundField.setValue(newValue);
}
public void addListener(ValueChangeListener listener) {
boundField.addListener(listener);
}
public void removeListener(ValueChangeListener listener) {
boundField.removeListener(listener);
}
public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
boundField.valueChange(event);
}
public Property getPropertyDataSource() {
return boundField.getPropertyDataSource();
}
public void setPropertyDataSource(Property newDataSource) {
boundField.setPropertyDataSource(newDataSource);
}
public void focus() {
boundField.focus();
}
public int getTabIndex() {
return boundField.getTabIndex();
}
public void setTabIndex(int tabIndex) {
boundField.setTabIndex(tabIndex);
}
public Object getValue() {
return boundField.getValue();
}
}
Using the custom component:
Field f = new TextFieldWithCalculatedLabelCustomComponent(gtmxAttrbts, "my label caption");
f.setPropertyDataSource(new BigDecimalFormatter(f.getPropertyDataSource()));
The formatter itself (just in case it's important):
public class BigDecimalFormatter extends PropertyFormatter {
public BigDecimalFormatter(Property propertyDataSource) {
super();
this.setPropertyDataSource(propertyDataSource);
}
@Override
public Object parse(String formattedValue) throws Exception {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat) nf;
df.applyPattern("###,###.#####");
Number d = df.parse(formattedValue);
return new BigDecimal(d.doubleValue());
}
@Override
public String format(Object value) {
NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat) nf;
df.applyPattern("###,###.#####");
return df.format(((BigDecimal) value).doubleValue());
}
}
See the difference using the same formatter for a plain Textfield vs Custom Component:
The plain Textfield respects the decimal delimiter being a comma. The custom component does not want the comma as a decimal delimiter :)
Any ideas? Thanks in advance.
Regards,
Jim