/* @ITMillApache2LicenseForJavaFiles@ */ package com.vaadin.data.util; import com.vaadin.data.Property; /** * Formatting proxy for a {@link Property}. * *
* This class can be used to implement formatting for any type of Property * datasources. The idea is to connect this as proxy between UI component and * the original datasource. *
* *
* For example
*
adds formatter for Double-typed property that extends
* standard "1.0" notation with more zeroes.
* textfield.setPropertyDataSource(new PropertyFormatter(property) {
public String format(Object value) {
return ((Double) value).toString() + "000000000";
}
public Object parse(String formattedValue) throws Exception {
return Double.parseDouble(formattedValue);
}
});
null
if
* none defined.
*/
public Property getPropertyDataSource() {
return dataSource;
}
/**
* Sets the specified Property as the data source for the formatter.
*
*
* * Remember that new data sources getValue() must return objects that are * compatible with parse() and format() methods. *
* * @param newDataSource * the new data source Property. */ public void setPropertyDataSource(Property newDataSource) { boolean readOnly = false; String prevValue = null; if (dataSource != null) { if (dataSource instanceof Property.ValueChangeNotifier) { ((Property.ValueChangeNotifier) dataSource) .removeListener(this); } if (dataSource instanceof Property.ReadOnlyStatusChangeListener) { ((Property.ReadOnlyStatusChangeNotifier) dataSource) .removeListener(this); } readOnly = isReadOnly(); prevValue = toString(); } dataSource = newDataSource; if (dataSource != null) { if (dataSource instanceof Property.ValueChangeNotifier) { ((Property.ValueChangeNotifier) dataSource).addListener(this); } if (dataSource instanceof Property.ReadOnlyStatusChangeListener) { ((Property.ReadOnlyStatusChangeNotifier) dataSource) .addListener(this); } } if (isReadOnly() != readOnly) { fireReadOnlyStatusChange(); } String newVal = toString(); if ((prevValue == null && newVal != null) || (prevValue != null && !prevValue.equals(newVal))) { fireValueChange(); } } /* Documented in the interface */ public Class getType() { return String.class; } /** * Get the formatted value. * * @return If the datasource returns null, this is null. Otherwise this is * String given by format(). */ public Object getValue() { return toString(); } /** * Get the formatted value. * * @return If the datasource returns null, this is null. Otherwise this is * String given by format(). */ @Override public String toString() { Object value = dataSource == null ? false : dataSource.getValue(); if (value == null) { return null; } return format(value); } /** Reflects the read-only status of the datasource. */ public boolean isReadOnly() { return dataSource == null ? false : dataSource.isReadOnly(); } /** * This method must be implemented to format the values received from * DataSource. * * @param value * Value object got from the datasource. This is guaranteed to be * non-null and of the type compatible with getType() of the * datasource. * @return */ abstract public String format(Object value); /** * Parse string and convert it to format compatible with datasource. * * The method is required to assure that parse(format(x)) equals x. * * @param formattedValue * This is guaranteed to be non-null string. * @return Non-null value compatible with datasource. * @throws Exception * Any type of exception can be thrown to indicate that the * conversion was not succesful. */ abstract public Object parse(String formattedValue) throws Exception; /** * Sets the Property's read-only mode to the specified status. * * @param newStatus * the new read-only status of the Property. */ public void setReadOnly(boolean newStatus) { if (dataSource != null) { dataSource.setReadOnly(newStatus); } } public void setValue(Object newValue) throws ReadOnlyException, ConversionException { if (dataSource == null) { return; } if (newValue == null) { if (dataSource.getValue() != null) { dataSource.setValue(null); fireValueChange(); } } else { try { dataSource.setValue(parse((String) newValue)); if (!newValue.equals(toString())) { fireValueChange(); } } catch (Exception e) { if (e instanceof ConversionException) { throw (ConversionException) e; } else { throw new ConversionException(e); } } } } /** * Listens for changes in the datasource. * * This should not be called directly. */ public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) { fireValueChange(); } /** * Listens for changes in the datasource. * * This should not be called directly. */ public void readOnlyStatusChange( com.vaadin.data.Property.ReadOnlyStatusChangeEvent event) { fireReadOnlyStatusChange(); } }