我有一个包含自定义组件的多行的表。我希望允许用户拖放行。
我尝试过以下代码,但无法拖动任何行:
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) {
}
});
答案 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);
}
});