123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- /*
- @ITMillApache2LicenseForJavaFiles@
- */
- package com.vaadin.data.util;
-
- import java.util.LinkedList;
-
- import com.vaadin.data.Property;
-
- /**
- * Formatting proxy for a property.
- *
- * <p>
- * 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.
- * </p>
- *
- * <p>
- * For example <code>
- * 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);
- }
-
- });</code> adds formatter for Double-typed property that extends standard
- * "1.0" notation with more zeroes.
- * </p>
- *
- * @author IT Mill Ltd.
- * @since 5.3.0
- */
- @SuppressWarnings("serial")
- public abstract class PropertyFormatter implements Property,
- Property.ValueChangeNotifier, Property.ValueChangeListener,
- Property.ReadOnlyStatusChangeListener,
- Property.ReadOnlyStatusChangeNotifier {
-
- /**
- * Internal list of registered value change listeners.
- */
- private LinkedList valueChangeListeners = null;
-
- /**
- * Internal list of registered read-only status change listeners.
- */
- private LinkedList readOnlyStatusChangeListeners = null;
-
- /** Datasource that stores the actual value. */
- Property dataSource;
-
- /**
- * Construct a new formatter that is connected to given datasource.
- *
- * @param propertyDataSource
- * to connect this property to.
- */
- public PropertyFormatter(Property propertyDataSource) {
-
- setPropertyDataSource(propertyDataSource);
- }
-
- /**
- * Gets the current data source of the formatter, if any.
- *
- * @return the current data source as a Property, or <code>null</code> if
- * none defined.
- */
- public Property getPropertyDataSource() {
- return dataSource;
- }
-
- /**
- * Sets the specified Property as the data source for the formatter.
- *
- *
- * <p>
- * Remember that new data sources getValue() must return objects that are
- * compatible with parse() and format() methods.
- * </p>
- *
- * @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) {
- dataSource.setValue(null);
- }
- 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);
- }
- }
-
- }
-
- /**
- * An <code>Event</code> object specifying the ObjectProperty whose value
- * has changed.
- *
- * @author IT Mill Ltd.
- * @since 5.3.0
- */
- private class ValueChangeEvent extends java.util.EventObject implements
- Property.ValueChangeEvent {
-
- /**
- * Constructs a new value change event for this object.
- *
- * @param source
- * the source object of the event.
- */
- protected ValueChangeEvent(PropertyFormatter source) {
- super(source);
- }
-
- /**
- * Gets the Property whose read-only state has changed.
- *
- * @return source the Property of the event.
- */
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-
- /**
- * An <code>Event</code> object specifying the Property whose read-only
- * status has been changed.
- *
- * @author IT Mill Ltd.
- * @since 5.3.0
- */
- private class ReadOnlyStatusChangeEvent extends java.util.EventObject
- implements Property.ReadOnlyStatusChangeEvent {
-
- /**
- * Constructs a new read-only status change event for this object.
- *
- * @param source
- * source object of the event
- */
- protected ReadOnlyStatusChangeEvent(PropertyFormatter source) {
- super(source);
- }
-
- /**
- * Gets the Property whose read-only state has changed.
- *
- * @return source Property of the event.
- */
- public Property getProperty() {
- return (Property) getSource();
- }
- }
-
- /**
- * Removes a previously registered value change listener.
- *
- * @param listener
- * the listener to be removed.
- */
- public void removeListener(Property.ValueChangeListener listener) {
- if (valueChangeListeners != null) {
- valueChangeListeners.remove(listener);
- }
- }
-
- /**
- * Registers a new value change listener for this ObjectProperty.
- *
- * @param listener
- * the new Listener to be registered
- */
- public void addListener(Property.ValueChangeListener listener) {
- if (valueChangeListeners == null) {
- valueChangeListeners = new LinkedList();
- }
- valueChangeListeners.add(listener);
- }
-
- /**
- * Registers a new read-only status change listener for this Property.
- *
- * @param listener
- * the new Listener to be registered
- */
- public void addListener(Property.ReadOnlyStatusChangeListener listener) {
- if (readOnlyStatusChangeListeners == null) {
- readOnlyStatusChangeListeners = new LinkedList();
- }
- readOnlyStatusChangeListeners.add(listener);
- }
-
- /**
- * Removes a previously registered read-only status change listener.
- *
- * @param listener
- * the listener to be removed.
- */
- public void removeListener(Property.ReadOnlyStatusChangeListener listener) {
- if (readOnlyStatusChangeListeners != null) {
- readOnlyStatusChangeListeners.remove(listener);
- }
- }
-
- /**
- * Sends a value change event to all registered listeners.
- */
- private void fireValueChange() {
- if (valueChangeListeners != null) {
- final Object[] l = valueChangeListeners.toArray();
- final Property.ValueChangeEvent event = new ValueChangeEvent(this);
- for (int i = 0; i < l.length; i++) {
- ((Property.ValueChangeListener) l[i]).valueChange(event);
- }
- }
- }
-
- /**
- * Sends a read only status change event to all registered listeners.
- */
- private void fireReadOnlyStatusChange() {
- if (readOnlyStatusChangeListeners != null) {
- final Object[] l = readOnlyStatusChangeListeners.toArray();
- final Property.ReadOnlyStatusChangeEvent event = new ReadOnlyStatusChangeEvent(
- this);
- for (int i = 0; i < l.length; i++) {
- ((Property.ReadOnlyStatusChangeListener) l[i])
- .readOnlyStatusChange(event);
- }
- }
- }
-
- /**
- * 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();
- }
-
- }
|