Problem with Drag'n Drop

Hi,

I build an application with a tree on the left hand and a TabSheet on the right hand. The TabSheet contains tables in different tabs. I want to drag’n drop the items from the table to the tree. The problem is, that the tables in the tabs are empty. Only a Table on the first selected tab contains values.

Example:


package com.example.bugtest;

import java.util.ArrayList;
import java.util.Collection;

import com.vaadin.annotations.AutoGenerated;
import com.vaadin.data.Container;
import com.vaadin.data.Item;
import com.vaadin.data.util.BeanContainer;
import com.vaadin.data.util.BeanItem;
import com.vaadin.event.DataBoundTransferable;
import com.vaadin.event.dd.DragAndDropEvent;
import com.vaadin.event.dd.DropHandler;
import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
import com.vaadin.event.dd.acceptcriteria.And;
import com.vaadin.event.dd.acceptcriteria.SourceIs;
import com.vaadin.ui.AbsoluteLayout;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.TabSheet;
import com.vaadin.ui.Table;
import com.vaadin.ui.Tree;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
import com.vaadin.ui.AbstractSelect.AcceptItem;
import com.vaadin.ui.Table.TableDragMode;
import com.vaadin.ui.Tree.TargetItemAllowsChildren;
import com.vaadin.ui.Tree.TreeDragMode;

public class TestComponent extends CustomComponent {

    private HorizontalLayout mainLayout;
    private Table testTable;
    private Tree testTree;

    public TestComponent() {
        mainLayout = new HorizontalLayout();
        
        testTree = new Tree();
        mainLayout.addComponent(testTree);

        TabSheet tabsheet = new TabSheet();
        tabsheet.addTab(new Label("Test for first side"), "First");
        
        testTable = new Table();
        testTable.setSizeFull();
        testTable.setSelectable(true);
        testTable.setMultiSelect(false);
        testTable.setDragMode(TableDragMode.ROW);
        testTable.setImmediate(true);
        tabsheet.addTab(testTable, "Table");
        
        mainLayout.addComponent(tabsheet);
        setCompositionRoot(mainLayout);
        
        Collection<Pojo> pojoEntries = new ArrayList<Pojo>();

        for (int i = 0; i < 10; i++) {
            Pojo p = new Pojo();
            p.setId(i + "");
            p.setText("This is " + i);
            pojoEntries.add(p);
        }

        BeanContainer<String, Pojo> container = new BeanContainer<String, Pojo>(Pojo.class);
        container.setBeanIdProperty(Pojo.ID);
        container.addAll(pojoEntries);
        
        
        testTable.setContainerDataSource(container);
        testTable.setColumnHeader(Pojo.TEXT, "Test Column");
        testTable.setVisibleColumns(new String[] { Pojo.TEXT });
        
        testTree.addContainerProperty("property1", String.class, null);
        testTree.addContainerProperty("property2", String.class, "");
        
        Item i = testTree.addItem("Test1");
        i.getItemProperty("property1").setValue("ID1");
        i.getItemProperty("property2").setValue("Test1 Display");
        
        testTree.setDragMode(TreeDragMode.NODE);
        testTree.setDropHandler(new DropHandler() {
            
            public AcceptCriterion getAcceptCriterion() {
                return new And(new SourceIs(testTable), TargetItemAllowsChildren.get(),
                        AcceptItem.ALL);
            }
            
            public void drop(DragAndDropEvent event) {
             // criteria verify that this is safe
                DataBoundTransferable t = (DataBoundTransferable) event
                        .getTransferable();
                Container sourceContainer = t.getSourceContainer();
                Object sourceItemId = t.getItemId();
                Item sourceItem = sourceContainer.getItem(sourceItemId);

                AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event
                            .getTargetDetails());
                Object targetItemId = dropData.getItemIdOver();
                
                
                Pojo p = ((BeanItem<Pojo>)sourceItem).getBean();
                
                Item newItem = testTree.addItem(p.getId());
                newItem.getItemProperty("property1").setValue(p.getId());
                newItem.getItemProperty("property2").setValue(p.getText());

                if (targetItemId != null) {
                    testTree.setParent(p.getId(), targetItemId);
                }
            }
        });
    }

    public class Pojo {

        public final static String ID = "id";
        public final static String TEXT = "text";

        private String id;
        private String text;

        /**
         * @param id the id to set
         */
        public void setId(String id) {
            this.id = id;
        }

        /**
         * @return the id
         */
        public String getId() {
            return id;
        }

        /**
         * @param text the text to set
         */
        public void setText(String text) {
            this.text = text;
        }

        /**
         * @return the text
         */
        public String getText() {
            return text;
        }
    }
}

When I remove the DropHandler from the Tree, the table contains all values.
I tried to add a SelectedTabChangeListener, that calls refreshRowCache() for the Table, but it has only an effect on the second time I select a empty tab.

I used vaadin 6.7.5 and 6.8.

Is there a workaround? Is this a bug in vaadin? Any help please.

Thanks alot in advance,

Pascal

I had this same issue – tables in the second and third tabs were not sized properly (small width/height) so they didn’t appear to the user.

I got around it by adding empty wrapper VerticalLayouts to the tabsheet and then a SelectedTabChangeListener. When the user selects the tab, I dynamically add the table to the wrapper layout.

Hi Jason,

thanks for this solution, but it doesn’t work in this case. The tables are still empty.
The problem is not the sizing of the table. I can see the table in firebug an it is over the complete tab, but it is still empty.

Do you have maybe an example? Maybe I did something other wrong. The wrapper alone is no solution.

Greating,
Pascal

Problem still exists.

Anybody any idea?