TreeTable addItemAfter

Should the additemAfter method work on a TreeTable? The call returns successfully, but the new node does not show up anywhere in the table that I can see.

Here’s a real simple example extending from the TreeTable sample code…


package com.example.vaadin;

import com.vaadin.Application;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Label;
import com.vaadin.ui.TreeTable;
import com.vaadin.ui.Window;

public class Vaadin2Application extends Application {
	
	TreeTable tr = new TreeTable("Simple test with builtin container");
    Object addItem2;


	@Override
	public void init() {
		Window mainWindow = new Window("Vaadin2 Application");
		Label label = new Label("Hello Vaadin user");
		mainWindow.addComponent(label);
		setMainWindow(mainWindow);
		
		mainWindow.addComponent(tr);

        // populate table
        tr.addContainerProperty("Foo", String.class, "foo");
        tr.addContainerProperty("Bar", String.class, "bar");
        Object addItem = tr.addItem();
        tr.getContainerProperty(addItem, "Foo").setValue("First");
        addItem2 = tr.addItem();
        tr.getContainerProperty(addItem2, "Foo").setValue("Second");
        Object addItem3 = tr.addItem();
        tr.getContainerProperty(addItem3, "Foo").setValue("Third");

        // build hierarchy
        tr.setParent(addItem3, addItem2);
        tr.setParent(addItem2, addItem);

        // flag to last item to be leaf
        tr.setChildrenAllowed(addItem3, false);

        // reserve excess space for the "treecolumn"
        tr.setWidth("100%");
        tr.setColumnExpandRatio("Foo", 1);
        
        Button lAddItemButton = new Button("Add Item");
        mainWindow.addComponent(lAddItemButton);
        
        lAddItemButton.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				Object lAddedItem = tr.addItem();
		        tr.getContainerProperty(lAddedItem, "Foo").setValue("New Add Item");
			}
		});
        
        Button lAddItemAfterButton = new Button("Add Item After");
        mainWindow.addComponent(lAddItemAfterButton);
        
        lAddItemAfterButton.addListener(new ClickListener() {
			public void buttonClick(ClickEvent event) {
				Object lAddedItem = tr.addItemAfter(addItem2);
		        tr.getContainerProperty(lAddedItem, "Foo").setValue("New Add Item After");
			}
		});
	}
}

The problem is that you don’t give a parent for the new item that you add under a branch.

It should work though, as items are not required to be added to the container in the order of the hierarchy, so this appears to be a bug (created
#7612
). Nevertheless, you can work around it by setting “setParent(lAddedItem, addItem)” in the listener.

If you just want to add the new item under a branch, you don’t need to add the item after the branch item in the container:

        Button lAddItemUnderButton = new Button("Add Item Under Branch");
        mainWindow.addComponent(lAddItemUnderButton);
       
        lAddItemUnderButton.addListener(new ClickListener() {
            public void buttonClick(ClickEvent event) {
                Object lAddedItem = tr.addItem();
                tr.setParent(lAddedItem, addItem);
                tr.getContainerProperty(lAddedItem, "Foo").setValue("New Add Item Under Branch");
            }
        });

Thanks for the info Marko!

For the bug ticket that you entered… do you think the fix will allow items to be added at a specific location in the hierarchy? Ultimately, I would like to add the item at a specific location among the children of the branch. I believe the workaround you showed will always display the item as the last child under the branch, right?

The case I mentioned was intentionally for adding as the last child in a branch. You can use the addItemAfter() for adding after a specific sibling, as long as you also use the setParent().

If the setParent() is missing, as it was in your code, the item
should
be displayed as the next root node after the subtree of the root node of the “after” item, in your case at the end of the treetable (as there is only one root node). The bug is that it is not displayed anywhere.

Even with the setparent some of the scenarios does not work. assume i have row1 and row2 under rows and if i want to add a row3 after to row1 it does not do it. instead it adds the row3 after row2. Is there any solution to this issues?

void additemafter(VerticalLayout layout) {
final TreeTable tr = new TreeTable();
tr.addContainerProperty(“Name”, String.class, “”);
tr.addContainerProperty(“Type”, String.class, “”);
layout.addComponent(tr);

        // populate table
        final Object rootId = tr.addItem();
        tr.getContainerProperty(rootId, "Name").setValue("Rows");
        tr.setCollapsed(rootId, false);
        
        final Object branch1Id = tr.addItem();
        tr.getContainerProperty(branch1Id, "Name").setValue("Row1");
        tr.setChildrenAllowed(branch1Id, false);
        tr.setParent(branch1Id, rootId);
        
        final Object branch2Id = tr.addItem();
        tr.getContainerProperty(branch2Id, "Name").setValue("Row2");
        tr.setChildrenAllowed(branch2Id, false);
        tr.setParent(branch2Id, rootId);
       

        tr.setWidth("100%");
        tr.setColumnExpandRatio("Name", 1);
       
        Button lAddItemAfterButton = new Button("Add Item After");
        layout.addComponent(lAddItemAfterButton);
       
        lAddItemAfterButton.addListener(new Button.ClickListener() {
            private static final long serialVersionUID = 1304303387443588874L;
            public void buttonClick(ClickEvent event) {
                Object newItemId = tr.addItemAfter(branch1Id);
                tr.setParent(newItemId, rootId);
                tr.setChildrenAllowed(newItemId, false);                    
                tr.getContainerProperty(newItemId, "Name").setValue("Row3");
            }
        });
    }