From 54aced3779391f3fc5985ad7c21992be672e7493 Mon Sep 17 00:00:00 2001 From: Matti Tahvonen Date: Tue, 11 Oct 2011 15:34:22 +0000 Subject: [PATCH] fix for #7776 svn changeset:21688/svn branch:6.7 --- src/com/vaadin/ui/AbstractField.java | 59 +++++++++++++++++++++------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/src/com/vaadin/ui/AbstractField.java b/src/com/vaadin/ui/AbstractField.java index b7666f6341..3619fbfdb3 100644 --- a/src/com/vaadin/ui/AbstractField.java +++ b/src/com/vaadin/ui/AbstractField.java @@ -90,11 +90,10 @@ public abstract class AbstractField extends AbstractComponent implements Field, private boolean modified = false; /** - * Should value change event propagation from property data source to - * listeners of the field be suppressed. This is used internally while the - * field makes changes to the property value. + * Flag to indicate that the field is currently committing its value to the + * datasource. */ - private boolean suppressValueChangePropagation = false; + private boolean committingValueToDataSource = false; /** * Current source exception. @@ -138,6 +137,8 @@ public abstract class AbstractField extends AbstractComponent implements Field, */ private ActionManager actionManager; + private boolean valueWasModifiedByDataSourceDuringCommit; + /* Component basics */ /* @@ -240,7 +241,8 @@ public abstract class AbstractField extends AbstractComponent implements Field, try { // Commits the value to datasource. - suppressValueChangePropagation = true; + valueWasModifiedByDataSourceDuringCommit = false; + committingValueToDataSource = true; dataSource.setValue(newValue); } catch (final Throwable e) { @@ -253,7 +255,7 @@ public abstract class AbstractField extends AbstractComponent implements Field, // Throws the source exception. throw currentBufferedSourceException; } finally { - suppressValueChangePropagation = false; + committingValueToDataSource = false; } } else { /* An invalid value and we don't allow them, throw the exception */ @@ -278,6 +280,8 @@ public abstract class AbstractField extends AbstractComponent implements Field, if (repaintNeeded) { requestRepaint(); } + + valueWasModifiedByDataSourceDuringCommit = false; } /* @@ -496,13 +500,14 @@ public abstract class AbstractField extends AbstractComponent implements Field, setInternalValue(newValue); modified = dataSource != null; + valueWasModifiedByDataSourceDuringCommit = false; // In write through mode , try to commit if (isWriteThrough() && dataSource != null && (isInvalidCommitted() || isValid())) { try { // Commits the value to datasource - suppressValueChangePropagation = true; + committingValueToDataSource = true; dataSource.setValue(newValue); // The buffer is now unmodified @@ -518,7 +523,7 @@ public abstract class AbstractField extends AbstractComponent implements Field, // Throws the source exception throw currentBufferedSourceException; } finally { - suppressValueChangePropagation = false; + committingValueToDataSource = false; } } @@ -528,8 +533,14 @@ public abstract class AbstractField extends AbstractComponent implements Field, requestRepaint(); } - // Fires the value change - fireValueChange(repaintIsNotNeeded); + if (!valueWasModifiedByDataSourceDuringCommit) { + // Fires the value change + fireValueChange(repaintIsNotNeeded); + } else { + // value change event already fired in valueChange() + valueWasModifiedByDataSourceDuringCommit = false; + + } } } @@ -996,13 +1007,33 @@ public abstract class AbstractField extends AbstractComponent implements Field, * changed. */ public void valueChange(Property.ValueChangeEvent event) { - if (!suppressValueChangePropagation - && (isReadThrough() && !isModified())) { - setInternalValue(event.getProperty().getValue()); - fireValueChange(false); + if (isReadThrough()) { + if (committingValueToDataSource) { + boolean propertyNotifiesOfTheBufferedValue = event + .getProperty().getValue() == value + || (value != null && value.equals(event.getProperty() + .getValue())); + if (!propertyNotifiesOfTheBufferedValue) { + /* + * Property (or chained property like PropertyFormatter) now + * reports different value than the one the field has just + * committed to it. In this case we respect the property + * value, fire value change listeners and repaint the field. + */ + readValueFromProperty(event); + valueWasModifiedByDataSourceDuringCommit = true; + } + } else if (!isModified()) { + readValueFromProperty(event); + } } } + private void readValueFromProperty(Property.ValueChangeEvent event) { + setInternalValue(event.getProperty().getValue()); + fireValueChange(false); + } + @Override public void changeVariables(Object source, Map variables) { super.changeVariables(source, variables); -- 2.39.5