|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.ObjectAbstractBean
com.jgoodies.binding.beans.Model
com.jgoodies.binding.value.AbstractValueModel
com.jgoodies.binding.value.BufferedValueModel
public final class BufferedValueModel
A ValueModel that wraps another ValueModel, the subject,
and delays changes of the subject's value. Returns the subject's value
until a value has been set. The buffered value is not written to the
subject until the trigger channel changes to Boolean.TRUE
.
The buffered value can be flushed by changing the trigger channel value
to Boolean.FALSE
. Note that the commit and flush events
are performed only if the trigger channel fires a change event. Since a
plain ValueHolder fires no property change event if a value is set that has
been set before, it is recommended to use a Trigger
instead
and invoke its #triggerCommit
and triggerFlush
methods.
The BufferedValueModel has been designed to behave much like its subject
when accessing the value. Therefore it throws all exceptions that would
arise when accessing the subject directly. Hence, attempts to read or
write a value while the subject is null
are always rejected
with a NullPointerException
.
This class provides the bound read-write properties subject and triggerChannel for the subject and trigger channel and a bound read-only property buffering for the buffering state.
The BufferedValueModel registers listeners with the subject and
trigger channel. It is recommended to remove these listeners by invoking
#release
if the subject and trigger channel live much longer
than this buffer. After #release
has been called
you must not use the BufferedValueModel instance any longer.
As an alternative you may use event listener lists in subjects and
trigger channels that are based on WeakReference
s.
If the subject value changes while this model is in buffering state this change won't show through as this model's new value. If you want to update the value whenever the subject value changes, register a listener with the subject value and flush this model's trigger.
Constraints: The subject is of type Object
,
the trigger channel value of type Boolean
.
ValueModel
,
ValueModel.getValue()
,
ValueModel.setValue(Object)
Field Summary | |
---|---|
static java.lang.String |
PROPERTYNAME_BUFFERING
The name of the bound read-only bean property that indicates whether this models is buffering or in write-through state. |
static java.lang.String |
PROPERTYNAME_SUBJECT
The name of the bound read-write bean property for the subject. |
static java.lang.String |
PROPERTYNAME_TRIGGER_CHANNEL
The name of the bound read-write bean property for the trigger channel. |
Fields inherited from class com.jgoodies.binding.value.AbstractValueModel |
---|
PROPERTYNAME_VALUE |
Constructor Summary | |
---|---|
BufferedValueModel(ValueModel subject,
ValueModel triggerChannel)
Constructs a BufferedValueModel on the given subject using the given trigger channel. |
Method Summary | |
---|---|
ValueModel |
getSubject()
Returns the subject, i.e. |
ValueModel |
getTriggerChannel()
Returns the ValueModel that is used to trigger commit and flush events. |
java.lang.Object |
getValue()
Returns the subject's value if no value has been set since the last commit or flush, and returns the buffered value otherwise. |
boolean |
isBuffering()
Returns whether this model buffers a value or not, that is, whether a value has been assigned since the last commit or flush. |
protected java.lang.String |
paramString()
Returns a string representing the state of this model. |
void |
release()
Removes the PropertyChangeListeners from the subject and trigger channel. |
void |
setSubject(ValueModel newSubject)
Sets a new subject ValueModel, i.e. |
void |
setTriggerChannel(ValueModel newTriggerChannel)
Sets the ValueModel that triggers the commit and flush events. |
void |
setValue(java.lang.Object newBufferedValue)
Sets a new buffered value and turns this BufferedValueModel into the buffering state. |
Methods inherited from class com.jgoodies.binding.value.AbstractValueModel |
---|
addValueChangeListener, booleanValue, doubleValue, fireValueChange, fireValueChange, fireValueChange, fireValueChange, fireValueChange, fireValueChange, fireValueChange, floatValue, getString, intValue, longValue, removeValueChangeListener, setValue, setValue, setValue, setValue, setValue, toString, valueString |
Methods inherited from class com.jgoodies.binding.beans.Model |
---|
createPropertyChangeSupport, firePropertyChange |
Methods inherited from class java.lang.Object |
---|
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Methods inherited from interface com.jgoodies.binding.beans.Observable |
---|
addPropertyChangeListener, removePropertyChangeListener |
Field Detail |
---|
public static final java.lang.String PROPERTYNAME_BUFFERING
isBuffering()
,
Constant Field Valuespublic static final java.lang.String PROPERTYNAME_SUBJECT
getSubject()
,
setSubject(ValueModel)
,
Constant Field Valuespublic static final java.lang.String PROPERTYNAME_TRIGGER_CHANNEL
getTriggerChannel()
,
setTriggerChannel(ValueModel)
,
Constant Field ValuesConstructor Detail |
---|
public BufferedValueModel(ValueModel subject, ValueModel triggerChannel)
subject
- the value model to be bufferedtriggerChannel
- the value model that triggers the commit or flush event
java.lang.NullPointerException
- if the triggerChannel is null
Method Detail |
---|
public ValueModel getSubject()
public void setSubject(ValueModel newSubject)
newSubject
- the subject ValueModel to be setpublic ValueModel getTriggerChannel()
public void setTriggerChannel(ValueModel newTriggerChannel)
newTriggerChannel
- the ValueModel to be set as trigger channel
java.lang.NullPointerException
- if the newTriggerChannel is null
public java.lang.Object getValue()
java.lang.NullPointerException
- if no subject is setpublic void setValue(java.lang.Object newBufferedValue)
The above semantics is easy to understand, however it is tempting to check the new value against the current subject value to avoid that the buffer unnecessary turns into the buffering state. But here's a problem. Let's say the subject value is "first" at buffer creation time, and let's say the subject value has changed in the meantime to "second". Now someone sets the value "second" to this buffer. The subject value and the value to be set are equal. Shall we buffer? Also, this decision would depend on the ability to read the subject. The semantics would depend on the subject' state and capabilities.
It is often sufficient to observe the buffering state when enabling or disabling a commit command button like "OK" or "Apply". And later check the changed state in a PresentationModel. You may want to do better and may want to observe a property like "defersTrueChange" that indicates whether flushing a buffer will actually change the subject. But note that such a state may change with subject value changes, which may be hard to understand for a user.
TODO: Consider adding an optimized execution path for the case
that this model is already in buffering state. In this case
the old buffered value can be used instead of invoking
#readBufferedOrSubjectValue()
.
newBufferedValue
- the value to be buffered
java.lang.NullPointerException
- if no subject is setpublic void release()
To avoid memory leaks it is recommended to invoke this method if the subject and trigger channel live much longer than this buffer. Once #release has been invoked the BufferedValueModel instance must not be used any longer.
As an alternative you may use event listener lists in subjects and
trigger channels that are based on WeakReference
s.
WeakReference
public boolean isBuffering()
protected java.lang.String paramString()
AbstractValueModel
null
.
paramString
in class AbstractValueModel
|
||||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||||
SUMMARY: NESTED | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |