addItemAfter in Tree not working as expected

Hello,

I’m trying to insert nodes in a tree at custom positions with addItemAfter() but it’s not working. I made a small test case, can anybody tell me what am I missing?


import com.vaadin.Application;
import com.vaadin.data.util.HierarchicalContainer;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;

public class TreeExample extends Application {

  public void init() {
    final Window mainWindow = new Window("testing");
    mainWindow.getContent().setHeight("100%");

    VerticalLayout layout = new VerticalLayout();
    Tree tree = new Tree("My Tree");
    HierarchicalContainer hc = new HierarchicalContainer();
    
    // Create the tree nodes
    hc.addItem("Root");
    hc.addItem("Branch 1");
    hc.addItem("Branch 2");
    hc.addItemAfter(null, "Branch 3");
    hc.addItem("Leaf 1");
    hc.addItem("Leaf 2");
    hc.addItem("Leaf 3");
    hc.addItem("Leaf 4");
    hc.addItem("Leaf 5");
    
    // Set the hierarchy
    hc.setParent("Branch 1", "Root");
    hc.setParent("Branch 2", "Root");
    hc.setParent("Branch 3", "Root");
    hc.setParent("Leaf 1", "Branch 1");
    hc.setParent("Leaf 2", "Branch 1");
    hc.setParent("Leaf 3", "Branch 2");
    hc.setParent("Leaf 4", "Branch 2");
    hc.setParent("Leaf 5", "Branch 3");
    tree.setContainerDataSource(hc);
    
    for (Object itemId: tree.getItemIds())
        tree.expandItem(itemId);
    
    layout.addComponent(tree);
    mainWindow.addComponent(layout);
    this.setMainWindow(mainWindow);
  }

}

“Branch 3” should be the first child of “Root”, right?

Hi,

this seems like a valid use case to me but does not actually work the way you would think it should work. I’d say either the documentation or implementation should be enhanced, please create a ticket for that into the Vaadin trac.

In the meantime, you should probably use
HierarchicalContainer.moveAfterSibling(Object itemId, Object siblingId)
which should correctly do what you need.

-tepi

created ticket
10904

as mentioned there, the workaround does not work if you want to move a node as first child. I tried

hc.addItemAt(0, "Branch 3"); instead of hc.addItemAfter(null,"Branch 3"); but that doesn’t work either! :open_mouth:

It does work for me. Here’s the container creation code I used (adapted from your code):


		HierarchicalContainer hc = new HierarchicalContainer();

		// Create the tree nodes
		hc.addItem("Root");
		hc.addItem("Branch 1");
		hc.addItem("Branch 2");
		hc.addItem("Branch 3");
		hc.addItem("Leaf 1");
		hc.addItem("Leaf 2");
		hc.addItem("Leaf 3");
		hc.addItem("Leaf 4");
		hc.addItem("Leaf 5");

		// Set the hierarchy
		hc.setParent("Branch 1", "Root");
		hc.setParent("Branch 2", "Root");
		hc.setParent("Branch 3", "Root");
		hc.setParent("Leaf 1", "Branch 1");
		hc.setParent("Leaf 2", "Branch 1");
		hc.setParent("Leaf 3", "Branch 2");
		hc.setParent("Leaf 4", "Branch 2");
		hc.setParent("Leaf 5", "Branch 3");
		
		hc.moveAfterSibling("Branch 3", null);
		tree.setContainerDataSource(hc);

I’m testing this on Vaadin 6.8.8 in case that makes a difference.

Yes it works. Sorry about that, I copy-paste-modified the addItemAfter method and din not switched the parameters.
I will update the ticket also.
Thanks.

What about the addItemAt method? Did you tested that too? (I don’t need it now but I’m curious)

HierarchicalContainer hc = new HierarchicalContainer();
    
    // Create the tree nodes
    hc.addItem("Root");
    hc.addItem("Branch 1");
    hc.addItem("Branch 2");
    hc.addItemAt(0, "Branch 3");
    hc.addItem("Leaf 1");
    hc.addItem("Leaf 2");
    hc.addItem("Leaf 3");
    hc.addItem("Leaf 4");
    hc.addItem("Leaf 5");
    
    // Set the hierarchy
    hc.setParent("Branch 1", "Root");
    hc.setParent("Branch 2", "Root");
    hc.setParent("Branch 3", "Root");
    hc.setParent("Leaf 1", "Branch 1");
    hc.setParent("Leaf 2", "Branch 1");
    hc.setParent("Leaf 3", "Branch 1");
    hc.setParent("Leaf 4", "Branch 2");
    hc.setParent("Leaf 5", "Branch 3");
    //hc.moveAfterSibling("Branch 3", null);
    tree.setContainerDataSource(hc);

The addItemAt doesn’t work for the children either. The issue seems to be that the HierarchicalContainer has its own ordered collections for the children, but the addItemAt and addItemAfter are only defined in IndexedContainer (which the HierarchicalContainer extends), so they would have no chance of modifying the child order. This might even be by design but at least I don’t see it documented in the javadoc of HierarchicalContainer.

A colleague just pointed out
this ticket
which seems to say that both methods are broken :(

Hopefully there will be a fix sooner or later.

I see. Thanks a lot guys.

Is this fixed now?