private boolean valueWasModifiedByDataSourceDuringCommit;
/**
- * Whether this field currently listens to Property events.
+ * Whether this field is currently registered as listening to events from
+ * its data source.
+ *
+ * @see #setPropertyDataSource(Property)
+ * @see #addPropertyListeners()
+ * @see #removePropertyListeners()
*/
- private boolean isListening = false;
+ private boolean isListeningToPropertyEvents = false;
/* Component basics */
* </p>
*
* <p>
+ * If the data source implements
+ * {@link com.vaadin.data.Property.ValueChangeNotifier} and/or
+ * {@link com.vaadin.data.Property.ReadOnlyStatusChangeNotifier}, the field
+ * registers itself as a listener and updates itself according to the events
+ * it receives. To avoid memory leaks caused by references to a field no
+ * longer in use, the listener registrations are removed on
+ * {@link AbstractField#detach() detach} and re-added on
+ * {@link AbstractField#attach() attach}.
+ * </p>
+ *
+ * <p>
* Note: before 6.5 we actually called discard() method in the beginning of
* the method. This was removed to simplify implementation, avoid excess
* calls to backing property and to avoid odd value change events that were
if (actionManager != null) {
actionManager.setViewer(getWindow());
}
- // No-op if listeners already registered
- addPropertyListeners();
+
+ if (!isListeningToPropertyEvents) {
+ addPropertyListeners();
+ if (!isModified() && isReadThrough()) {
+ // Update value from data source
+ discard();
+ }
+ }
}
@Override
}
}
+ /**
+ * Registers this as an event listener for events sent by the data source
+ * (if any). Does nothing if
+ * <code>isListeningToPropertyEvents == true</code>.
+ */
private void addPropertyListeners() {
- if (!isListening) {
+ if (!isListeningToPropertyEvents) {
if (dataSource instanceof Property.ValueChangeNotifier) {
((Property.ValueChangeNotifier) dataSource).addListener(this);
}
((Property.ReadOnlyStatusChangeNotifier) dataSource)
.addListener(this);
}
- isListening = true;
+ isListeningToPropertyEvents = true;
}
}
+ /**
+ * Stops listening to events sent by the data source (if any). Does nothing
+ * if <code>isListeningToPropertyEvents == false</code>.
+ */
private void removePropertyListeners() {
- if (isListening) {
+ if (isListeningToPropertyEvents) {
if (dataSource instanceof Property.ValueChangeNotifier) {
((Property.ValueChangeNotifier) dataSource)
.removeListener(this);
((Property.ReadOnlyStatusChangeNotifier) dataSource)
.removeListener(this);
}
- isListening = false;
+ isListeningToPropertyEvents = false;
}
}
}
\ No newline at end of file