Update HierarchicalContainer Item not working

hi!

situation: toolbox on the left, drag and drop fields on the tree.

items in the tree have properties (different for each item. click item in the tree to see them in the details window) that can be changed by clicking save.

problem: the itemProperty does not change but the tree item caption does (“Date” would change to “Order date” in Screenshot when i click save) but the underlying itemProperty still holds “Date”.


Source:

http://www.file-upload.net/download-8857787/WowiPreview1.rar.html

Class of the items:

[code]
public class ProtocolItem
{
private UUID id;
private UUID parentId;
private Integer index;
private String itemType;
private String itemTypeCaption;
private HashMap<String, Object> params;

.....

}
[/code]params is a HashMap and stores properties of the Items. A ProtocolItem of type “date” e.g. has Hint, Date and Caption.

here you can see how i create the tree’s container, which holds one ProtocolItem of type “window” at the beginning. Here you can see what that params HashMap is used for. Window has properties caption and sections. String stores internal name and display name, object stores the actual value of the property.

private HierarchicalContainer getContainer()
    {
        ProtocolItem root = new ProtocolItem("Window", "window");

        HierarchicalContainer container = new HierarchicalContainer();

        container.addContainerProperty("id", UUID.class, null);
        container.addContainerProperty("itemTypeCaption", String.class, null);
        container.addContainerProperty("itemType", String.class, null);
        container.addContainerProperty("params", HashMap.class, null);

        HashMap<String[], Object> params = new HashMap<String[]
, Object>();
        params.put(new String[]{"caption", "Protocol"}, "");
        params.put(new String[]{"sections", "Sections"}, new ArrayList<ProtocolItem>());
        root.setParams(params);
        
        Item item = null;
        item = container.addItem(root);
        item.getItemProperty("id").setValue(root.getId());
        item.getItemProperty("itemTypeCaption").setValue(root.getItemTypeCaption());
        item.getItemProperty("itemType").setValue(root.getItemType());        
        item.getItemProperty("params").setValue(root.getParams());
        
        container.setChildrenAllowed(root, true);

        return container;
    }

i set that container as datasource for the tree by:

      treeProtocol.setContainerDataSource(getContainer());
     treeProtocol.setVisibleColumns(new Object[] { "itemTypeCaption" });

okay… now i drop an item from toolbox to the tree:

private void handleItemDrop(Container _container, ProtocolItem item, ProtocolItem targetItem, VerticalDropLocation location, boolean allowChildren)
    {
        HierarchicalContainer container = (HierarchicalContainer) _container;

        //new item from Toolbox
        if (item.getId() == null)
        {
            item.setId(UUID.randomUUID());
            Item containerItem = null;
            containerItem = container.addItem(item);
            containerItem.getItemProperty("id").setValue(item.getId());
            containerItem.getItemProperty("itemTypeCaption").setValue(item.getItemTypeCaption());
            containerItem.getItemProperty("itemType").setValue(item.getItemType());

            //params
            HashMap<String[], Object> params = new HashMap<String[]
, Object>();
            
            switch (item.getItemType())
            {
                case "window":
                    params.put(new String[]{"caption", "Caption"}, "");
                    params.put(new String[]{"sections", "Sections"}, new ArrayList<ProtocolItem>());
                    break;
                case "section":
                    params.put(new String[]{"header", "Header"}, "");
                    params.put(new String[]{"footer", "Footer"}, "");
                    params.put(new String[]{"items", "Fields"}, new ArrayList<ProtocolItem>());
                    break;
                case "text":
                    params.put(new String[]{"caption", "Caption"}, "");
                    params.put(new String[]{"value", "Text"}, "");
                    params.put(new String[]{"hint", "Hint"}, "Input text please...");
                    params.put(new String[]{"isNumeric", "Numeric"}, false);
                    params.put(new String[]{"isMultiLine", "Multiline"}, false);
                    break;
                case "date":
                    params.put(new String[]{"caption", "Caption"}, "");
                    params.put(new String[]{"value", "Date"}, new Date());
                    params.put(new String[]{"hint", "Hint"}, "");        
                    break;
                case "switch":
                    params.put(new String[]{"caption", "Caption"}, "");
                    params.put(new String[]{"value", "Yes/No"}, false);
                    params.put(new String[]{"hint", "Hint"}, "");        
                    break;
                case "combo":
                    params.put(new String[]{"caption", "Caption"}, "");
                    params.put(new String[]{"value", "Selected Item"}, "");
                    params.put(new String[]{"hint", "Hint"}, "");
                    params.put(new String[]{"items", "Values"}, new ArrayList<String>());
                    break;
            }
            
            item.setParams(params);
            containerItem.getItemProperty("params").setValue(item.getParams());
            container.setChildrenAllowed(item, allowChildren);
        }

        
        //handle drop position
        if (location == VerticalDropLocation.MIDDLE)
        {
            if (container.setParent(item, targetItem) && container.hasChildren(targetItem))
            {
                Integer count = container.getChildren(targetItem).size();
                container.addItemAt(count);
            }
        } else if (location == VerticalDropLocation.TOP)
        {
            //parent of target!
            final Object targetParentItem = container.getParent(targetItem);
            if (container.setParent(item, targetParentItem))
            {
                container.moveAfterSibling(item, targetItem);
                container.moveAfterSibling(targetItem, item);
            }
        } else if (location == VerticalDropLocation.BOTTOM)
        {
            //parent of target!
            final Object targetParentItem = container.getParent(targetItem);
            if (container.setParent(item, targetParentItem))
            {
                container.moveAfterSibling(item, targetItem);
            }
        }
    }

Display the item and its properties on click:

        treeProtocol.addItemClickListener(new ItemClickListener()
        {
            private static final long serialVersionUID = 32453454;

            @Override
            public void itemClick(ItemClickEvent event)
            {
                currentItem = (ProtocolItem) event.getItemId();
                
                showItemDetails(currentItem, (HierarchicalContainer) treeProtocol.getContainerDataSource());
            }
        });

       private void showItemDetails(final ProtocolItem item, final HierarchicalContainer container)
       {
        layoutDetails.removeAllComponents();       
        
        HashMap<String[], Object> m = item.getParams();
        
        for (Map.Entry<String[], Object> entry : m.entrySet()) {
            
            if (entry.getValue() instanceof String)
            {                
                TextField txtValue = new TextField(entry.getKey()[1]
.toString());
                txtValue.setData(entry.getKey()[0]
.toString());
                //DEBUG TESTING: value of any TextField = itemTypeCaption
                //====================================================
                txtValue.setValue(item.getItemTypeCaption());//entry.getValue().toString());
                layoutDetails.addComponent(txtValue);    
            }
            if (entry.getValue() instanceof Date)
            {                
                DateField dateValue = new DateField(entry.getKey()[1]
.toString());
                dateValue.setData(item);
                dateValue.setValue((Date)entry.getValue());
                layoutDetails.addComponent(dateValue);    
            }
            else if (entry.getValue() instanceof Boolean)
            {
                CssLayout checkLayout = new CssLayout();    
                checkLayout.setCaption(entry.getKey()[1]
.toString());
                CheckBox checkValue = new CheckBox();                
                checkValue.setValue((Boolean)entry.getValue());
                checkLayout.addComponent(checkValue);                
                layoutDetails.addComponent(checkLayout);    
            }
            else if (entry.getValue() instanceof ArrayList<?>)
            {
                layoutDetails.addComponent(new Label(entry.getKey()[1]
.toString() + ": " + ((ArrayList)entry.getValue()).size()));
            }
            
        }
        
        Button btnSaveItem = new Button("Save");
        btnSaveItem.addClickListener(new ClickListener()
        {        
            private static final long serialVersionUID = -6317950193445035450L;

            @Override
            public void buttonClick(ClickEvent event)
            {
                //DEBUG TESTING: set itemTypeCaption to "test123" --> should be displayed in any TextField !!!
                Item i = container.getItem(item);
                i.getItemProperty("itemTypeCaption").setValue("test123");
                
                //==> Tree gets updated and display "test123" but itemProperty not -> TextField is still displaying old value. why??
            }
        });
        layoutDetails.addComponent(btnSaveItem);
    }

Tree updates, itemProperty doesn’t. Any idea? I can’t believe it’s so difficult to update that items data!? :confused:

best regards!!

okay… i got it (!) but really need an explanation of whats going on there to understand it…! Much text but problem is solved. Maybe someone else finds that useful, too.

(

red

is old and
doesn’t work
,

green

is new and
works
)

what i did in the TreeTable ClickListener was getting my bean object (class ProtocolItem) out of the event and then passing it to my showItemDetails method which handles the later update, too. Now i get the IndexedContainerItem of the event and pass that instead:

[b]
//doesn't work:
[/b]
[color=#FF0000]
ProtocolItem 
[/color]currentItem;
public void itemClick(ItemClickEvent event)
{
     currentItem = [color=#FF0000]
(ProtocolItem)
[/color] event.[color=#FF0000]
[b]
getItemId
[/b]
[/color]();               
     showItemDetails(currentItem, (HierarchicalContainer) treeProtocol.getContainerDataSource());
}

[b]
//works:
[/b]
[b]
[color=#008000]
Item 
[/color]
[/b]currentItem;
public void itemClick(ItemClickEvent event)
{
     currentItem = event.[b]
[color=#008000]
getItem()
[/color]
[/b];               
     showItemDetails(currentItem, (HierarchicalContainer) treeProtocol.getContainerDataSource());
}

in the showItemDetails method i’ve read the values of my bean by using the
getters of the

bean
. Now i get the property values out of the IndexedContainerItem with .getItemProperty(…).getValue() method.

      
[color=#FF0000]
[b]
//doesn't work
[/b]
[/color]
       private void showItemDetails(final [b]
[color=#FF0000]
ProtocolItem item
[/color]
[/b], final HierarchicalContainer container)
       {
        layoutDetails.removeAllComponents();       
        
        HashMap<String, Object> m = [color=#FF0000]
[b]
item.getParams()
[/b]
[/color];
        
        for (Map.Entry<String, Object> entry : m.entrySet()) {
            
            if (entry.getValue() instanceof String)
            {                
                TextField txtValue = new TextField(entry.getKey()[1]
.toString());               
                txtValue.setValue([b]
[color=#FF0000]
item.getItemTypeCaption()
[/color]
[/b]);
                layoutDetails.addComponent(txtValue);    
            }
            .....
        }
        
        Button btnSaveItem = new Button("Save");
        btnSaveItem.addClickListener(new ClickListener()
        {      
            @Override
            public void buttonClick(ClickEvent event)
            {
                Item [color=#FF8C00]
[b]
i
[/b]
[/color] = container.getItem([b]
[color=#FF0000]
item
[/color]
[/b]); //[color=#FF8C00]
i = Item.class - (IndexedContainerItem)
[/color] ## [color=#FF0000]
item = ProtocolItem.Class (Bean)
[/color]
                
                [color=#FF8C00]
[b]
i
[/b]
[/color].getItemProperty("itemTypeCaption").setValue("test123"); [b]
[color=#FF8C00]
//setting the value in the IndexedContainerItem's property
[/color]
[/b]
            }
        });
        layoutDetails.addComponent(btnSaveItem);
        }



[b]
[color=#008000]
//works
[/color]
[/b]
       private void showItemDetails(final [b]
[color=#008000]
Item item
[/color]
[/b], final HierarchicalContainer container)
       {
        layoutDetails.removeAllComponents();       
        
        HashMap<String, Object> m = [b]
[color=#008000]
(HashMap<String, Object>)item.getItemProperty("params").getValue()
[/color]
[/b];
        
        for (Map.Entry<String, Object> entry : m.entrySet()) {
            
            if (entry.getValue() instanceof String)
            {                
                TextField txtValue = new TextField(entry.getKey()[1]
.toString());               
                txtValue.setValue([b]
[color=#008000]
item.getItemProperty("itemTypeCaption").getValue().toString()
[/color]
[/b]);
                layoutDetails.addComponent(txtValue);    
            }
            .....
        }
       
        Button btnSaveItem = new Button("Save");
        btnSaveItem.addClickListener(new ClickListener()
        {      
            @Override
            public void buttonClick(ClickEvent event)
            {
                [b]
[color=#008000]
item.getItemProperty("itemTypeCaption").setValue("test123")
[/color]
[/b]; [b]
[color=#FF8C00]
//setting the value in the IndexedContainerItem's property
[/color]
[/b]
            }
        });
        layoutDetails.addComponent(btnSaveItem);
        }

after updating the value with IndexedContainerItem.getItemProperty(…).setValue(…) i couldn’t read the updated values of the bean (referred to as “ItemId”?) using the getters of each property.
if i use the getItemProperty(…).getValue() method of the IndexedContainerItem i get the actual updated value.

Can someone explain that to me please? why aren’t the properties of the actual bean (ItemId which refers to the Item in the container) updated but i get the updated values with the above mentioned method of the Item itself?

Thanks!!!

okay i’m getting into it (slowly)…

when using containers with beans in it and you want to read/update some data it seems you shall
not
mix
bean getters/setters
with
ContainerItem.getItemProperty(…).getValue()/setValue(…)

both work if you use them alone, meaning updating and reading properties with either one or the other “technique”.
if i want to update values with bean setters, i must read them by using bean getters.
If i want to use the setValue method of the ContainerItem to update values i must use getValue method to read them again.


ItemId is the Bean
with e.g. name property set to “Michael”.

Item
is the
corresponding container item
(row).

If i update the
Item
with
IndexedContainerItem.getItemProperty(“name”).setValue(“Paul”)
I’m actually adressing a property that i defined
within the bean
?! But if I want to get the new value with
ItemId.getName()
it still says “Michael”.
I must use
IndexedContainerItem.getItemProperty(“name”).getValue()
to get “Paul”.

Any explanation is welcome :slight_smile: