*/
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.
+ */
+ private boolean suppressValueChangePropagation = false;
+
/**
* Current source exception.
*/
try {
// Commits the value to datasource.
+ suppressValueChangePropagation = true;
dataSource.setValue(newValue);
} catch (final Throwable e) {
// Throws the source exception.
throw currentBufferedSourceException;
+ } finally {
+ suppressValueChangePropagation = false;
}
} else {
/* An invalid value and we don't allow them, throw the exception */
try {
// Commits the value to datasource
+ suppressValueChangePropagation = true;
dataSource.setValue(newValue);
// The buffer is now unmodified
// Throws the source exception
throw currentBufferedSourceException;
+ } finally {
+ suppressValueChangePropagation = false;
}
}
* This method listens to data source value changes and passes the changes
* forwards.
*
+ * Changes are not forwarded to the listeners of the field during internal
+ * operations of the field to avoid duplicate notifications.
+ *
* @param event
* the value change event telling the data source contents have
* changed.
*/
public void valueChange(Property.ValueChangeEvent event) {
- if (isReadThrough() || !isModified()) {
+ if (!suppressValueChangePropagation
+ && (isReadThrough() || !isModified())) {
fireValueChange(false);
}
}
@Override
public void handleAction(Object sender, Object target) {
- this.focusable.focus();
+ focusable.focus();
}
}
}
\ No newline at end of file