如何允许用户在vaadin表中拖放行?

时间:2015-12-23 10:34:56

标签: java vaadin

我有一个包含自定义组件的多行的表。我希望允许用户拖放行。

我尝试过以下代码,但无法拖动任何行:

tblStructure = new Table();
tblStructure.setSizeFull();
tblStructure.setSelectable(false);
tblStructure.setSortEnabled(false);
tblStructure.setDragMode(Table.TableDragMode.ROW);
tblStructure.setNullSelectionAllowed(true);
tblStructure.setDropHandler(new DropHandler() {

        /**
         * 
         */
        private static final long serialVersionUID = 1L;

        @Override
        public AcceptCriterion getAcceptCriterion() {
            return AcceptAll.get();
        }

        @Override
        public void drop(DragAndDropEvent event) {
        }
    });

3 个答案:

答案 0 :(得分:1)

我知道我正在回应旧线程。我发现在Vaadin中可能会非常麻烦。我拒绝使用TreeTable或其他组件来实现此结果。我想与搜索此内容的任何人分享我的解决方案,因为我自己找不到简单明了的答案。此外,我想为社区做一些事情,因为我们使用了大量的开源软件。

创建一个类,例如SortableTable,它扩展了常规的Vaadin表。

public class SortableTable extends Table {
    private static final long serialVersionUID = 1L;

    public SortableTable() {
        setDragMode(TableDragMode.ROW);
        setSelectable(true);
        setDropHandler(new DropHandler() {
            private static final long serialVersionUID = 1L;

            @Override
            public AcceptCriterion getAcceptCriterion() {
                return AcceptAll.get();
            }

            @Override
            public void drop(DragAndDropEvent event) {
                Transferable t = event.getTransferable();
                Object sourceItemId = t.getData("itemId");

                AbstractSelectTargetDetails dropData = (AbstractSelectTargetDetails)event.getTargetDetails();
                Object targetItemId = dropData.getItemIdOver();

                switch(dropData.getDropLocation()) {
                case BOTTOM:
                    moveAfter(targetItemId, sourceItemId);
                    break;
                case MIDDLE:
                case TOP:
                    final Object prevItemId = prevItemId(targetItemId);
                    moveAfter(prevItemId, sourceItemId);
                    break;
                }
            }
        });
    }
...

接下来,创建此自定义函数以移动表项。

    @SuppressWarnings("unchecked")
    /**
     * 
     * @param targetItemId
     * @param sourceItemId
     * @return ItemId of the object the item moved to
     */
    public Object moveAfter(Object targetItemId, Object sourceItemId) {
        if(sourceItemId == null)
            return null;
        Item sourceItem = getItem(sourceItemId);

        Object[] propertyIds = getContainerPropertyIds().toArray();
        int size = propertyIds.length;
        Object[][] properties = new Object[size][2];

        // backup source item properties and values
        for(int i = 0; i < size; i++) {
            Object propertyId = propertyIds[i];
            Object value = sourceItem.getItemProperty(propertyId).getValue();
            properties[i][0] = propertyId;
            properties[i][1] = value;
        }
        removeItem(sourceItemId);
        Item item = addItemAfter(targetItemId, sourceItemId);

        // restore source item properties and values
        for(int i = 0; i < size; i++) {
            Object propertyId = properties[i][0];
            Object value = properties[i][1];
            item.getItemProperty(propertyId).setValue(value);
        }

        return sourceItemId;
    }


}

让我们试着解释一下。由于某些显而易见的原因,在调用removeItem时,表项完全被删除并从表中删除。除了将其属性和值复制到新行之外,无法将同一对象放回到表中。这正是自定义moveAfter所做的。代码的另一部分的灵感来自于内布拉斯在之前的帖子中提到的Vaadin采样器中的“树到表拖动 - 降落”示例。

我希望我能用这篇文章帮助别人。问候! :)

答案 1 :(得分:0)

您需要在drop(DragAndDropEvent event)方法中编写逻辑。在这里,您有两个链接,其中包含更多信息:

答案 2 :(得分:-1)

将包含逻辑的代码添加到drop(..)方法中。 以下代码来自vaadin sampler拖放示例:

table.setDragMode(TableDragMode.ROW);
    table.setDropHandler(new DropHandler() {
        @Override
        public void drop(final DragAndDropEvent dropEvent) {
            // criteria verify that this is safe
            final DataBoundTransferable t = (DataBoundTransferable) dropEvent
                    .getTransferable();
            if (!(t.getSourceContainer() instanceof Container.Hierarchical)) {
                return;
            }
            final Container.Hierarchical source = (Container.Hierarchical) t
                    .getSourceContainer();

            final Object sourceItemId = t.getItemId();

            // find and convert the item(s) to move

            final Object parentItemId = source.getParent(sourceItemId);
            // map from moved source item Id to the corresponding Hardware
            final LinkedHashMap<Object, Hardware> hardwareMap = new LinkedHashMap<Object, Hardware>();
            if (parentItemId == null) {
                // move the whole subtree
                final String category = getTreeNodeName(source,
                        sourceItemId);
                final Collection<?> children = source
                        .getChildren(sourceItemId);
                if (children != null) {
                    for (final Object childId : children) {
                        final String name = getTreeNodeName(source, childId);
                        hardwareMap.put(childId, new Hardware(name,
                                category));
                    }
                }
            } else {
                // move a single hardware item
                final String category = getTreeNodeName(source,
                        parentItemId);
                final String name = getTreeNodeName(source, sourceItemId);
                hardwareMap.put(sourceItemId, new Hardware(name, category));
            }

            // move item(s) to the correct location in the table

            final AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) dropEvent
                    .getTargetDetails());
            final Object targetItemId = dropData.getItemIdOver();

            for (final Object sourceId : hardwareMap.keySet()) {
                final Hardware hardware = hardwareMap.get(sourceId);
                if (targetItemId != null) {
                    switch (dropData.getDropLocation()) {
                    case BOTTOM:
                        tableContainer.addItemAfter(targetItemId, hardware);
                        break;
                    case MIDDLE:
                    case TOP:
                        final Object prevItemId = tableContainer
                                .prevItemId(targetItemId);
                        tableContainer.addItemAfter(prevItemId, hardware);
                        break;
                    }
                } else {
                    tableContainer.addItem(hardware);
                }
                source.removeItem(sourceId);
            }
        }

        @Override
        public AcceptCriterion getAcceptCriterion() {
            return new And(acceptCriterion, AcceptItem.ALL);
        }
    });
相关问题