Get informed about Property update in a Container

Hi,

I have one simple problem: I’ve got an IndexedContainer and need to get informed when a property inside this container is updated. So far there is no Problem - simply register a ValueChangeListener and whenever a property changes the handler method is called.
The tricky part begins now when I want to get the item-Id and the property-id of the property which was changed. There is a private class called IndexedContainerProperty inside of IndexedContainer which calls the private method IndexedContainer#firePropertyValueChange() if its value changes. But since these two things are private I don’t see any nice way to get there. Did I miss something here?

Thanks for all ideas, Patrick

Unfortunately this is not as easy as it should be. In the ValueChangeEvent, you do get the Property instance that changed, but not the rest of the information, and some of the relevant methods are private. IndexedContainer has quite a few limitations, and is not really extensible currently.

Your easiest option would probably be to register the listeners separately for each Property in the Container - somewhat ugly, but should be doable with methods you can call or override. Alternatively, you could try to use another Container from Vaadin or the
Directory
that makes this easier, although I think at least none of the standard containers make this trivial.

Note that there is a reason why there is no easy way to listen to all property changes directly through the Container interface: a Container could have hundreds of thousands of items, most of which are not in memory at any given time but obtained from a database or a web service or some other source on demand.

The Table component, to do its UI updates, listens to changes of Properties that have been displayed (or are in the scroll buffer around the displayed area), not all properties.

You could
create an enhancement request
to have an easier way to do this at least for IndexedContainer, where everything is in memory anyway - I believe this would make things easier for many users.

Thanks really much for your quick reply. I made an
enhancement Request
to get things easier in the future…

I know this is a pretty old thread, but it seems like it has not been resolved yet… IndexedContainerProperty class is still private so I can’t cast the property to know which item ID ant Property ID was changed. I have created an enhancement request http://dev.vaadin.com/ticket/13121

For now, I am using very dirty and

really really hacky solution

, basically forcibly digging those values from that object with a pickaxe (Java Reflection). I am actually surprised Tomcat lets me do that…

public void valueChange(ValueChangeEvent event) {
                if (!sledujZmeny)
                    return;
                
                
                Property<String> property = event.getProperty();
                Class clazz = property.getClass();
                Integer itemId = -1;
                String propertyId = "";
                try {
                    Field itemIdField = clazz.getDeclaredField("itemId");
                    Field propertyIdField = clazz.getDeclaredField("propertyId");
                    itemIdField.setAccessible(true);
                    propertyIdField.setAccessible(true);                    
                    itemId = (Integer) itemIdField.get(property);
                    propertyId = (String) propertyIdField.get(property);
                    
                } catch (Exception e) {
                    logger.error("Chyba", e);
                }
                logger.debug("Daco sa zmenilo {}", property.getValue());

            }