Is there a way how to receive an event on PropertyDataSource when a Field was detached from UI? Currently I am using AbstractProperty#removeValueChangeListener() however it is probably not clean. Anything like Property.AttachDetachNotifier should be better way.
There is no such generic listener at the moment, you could
create an enhancement request
if you think an interface for supporting this in properties is needed.
Note that a Property can be bound to multiple fields or other Properties at the same time, properties can be chained, there can be value change listeners which are “borderline” between the property being attached somewhere or not etc. Furthermore, some property instances are “transient” in a sense - for instance, a container can handle the listeners for a property itself and use lightweight property instances that are recreated on every getItemProperty(…) or getContainerProperty(…) and delegate all operations to the container.
The reason why we need this feature is the requirement to show live data comming from technology process. Our Property subscribes for source data changes and to avoid memory leaks we need tu unsubscribe the source if no more active Property consumers exist. Any idea how to solve it using current API?
I would say tracking (un)registration of ValueChangeListener would be the way to go if you are using customized Property classes where that is easy to implement - just override the add/removeValueChangeListener methods to keep track if there are any active listeners. That is also the logical place for this if the Property is handling the rest of subscribing and unsubcribing to the underlying data source: when nobody is interested in the values, stop tracking changes internally without caring what were the classes that were registered as listeners.
If using a container that does not give control over the Property instances created, though, this gets tricky with the current API.
Thanks, that’s what I am currently doing. Until now works fine for me.
There are still few issues. I implemented MyProperty with subscriber for changes on underlying data. When the data source changes, I call fireValueChange(). MyProperty is readOnly and is data source for TextField. When the layout opens, I get the exception
java.lang.IllegalStateException: A connector should not be marked as dirty while a response is being written.
and the TextField caption has a red marker with error message ‘could not convert value to …’ .
Are the changes being performed in a background thread? Proper locking etc. is necessary in that case. For Vaadin 7.1, UI.access(Runnable) is the way to do this when receiving a notification from the back-end.
See also the mini-tutorials on polling or pushing changes
here
.
UI.access(Runnable) is the way for standard request scope. I did not found any way how to get UI reference in background thread except passing UI instance ref to Property constructor. Not sure if it’s the right way but it works at least now for me.
If I remember correctly, once inside the UI.access Runnable, the appropriate ThreadLocals will be set so UI.getCurrent() should work. Thus, you only need to pass the UI up to the point where you need it to call ui.access(…).
Misunderstanding, you are right, of course UI.access(Runnable) works fine, only UI.getCurrent() returns null if called from background thread - this means my Subscriber, listening for underlying data changes, does not know anything about UI. Passing UI reference to Property constructor is one way. Another is calling UI.getCurrent() in Property constructor, because typical Property instance is created in request scope. Thanks for your help.