DragDropPane pane3 = new DragDropPane();
pane3.setSizeFull();
pane3.setCaption("Pane3");
final Tree t = new Tree(
"Tree with sorting enabled. Also allows dragging elsewhere.");
final HierarchicalContainer idx = new HierarchicalContainer();
t.setContainerDataSource(idx);
t.setId("perseys");
t.addItem("Foo");
t.addItem("Bar");
t.addItem("Bar1");
t.addItem("Bar2");
t.addItem("Bar3");
t.addItem("Bar4");
t.addItem("Bar5");
t.addItem("Child");
t.setParent("Child", "Foo");
t.setSizeFull();
t.setDragMode(TreeDragMode.NODE);
/*
* Moves items in tree (and could work in Table too). Also supports
* "building" tree.
*
* TODO fix algorithm, broken in some cases.
*/
DropHandler itemSorter = new DropHandler() {
@SuppressWarnings("unused")
private void populateSubTree(HierarchicalContainer idx,
HierarchicalContainer subtree, Object itemId) {
Collection<?> children = subtree.getChildren(itemId);
if (children != null) {
for (Object childId : children) {
Item addItem = idx.addItem(childId);
if (addItem != null) {
// did not exist, populate properties
Item item = subtree.getItem(itemId);
Collection<?> itemPropertyIds = item
.getItemPropertyIds();
for (Object propId : itemPropertyIds) {
addItem.getItemProperty(propId)
.setValue(
item.getItemProperty(propId)
.getValue());
}
}
idx.setParent(childId, itemId);
populateSubTree(idx, subtree, childId);
}
}
}
@SuppressWarnings("unused")
private HierarchicalContainer getSubTree(HierarchicalContainer idx,
Object itemId) {
HierarchicalContainer hierarchicalContainer = new HierarchicalContainer();
Collection<?> containerPropertyIds = idx
.getContainerPropertyIds();
for (Object object : containerPropertyIds) {
hierarchicalContainer.addContainerProperty(object,
idx.getType(object), null);
}
hierarchicalContainer.addItem(itemId);
copyChildren(idx, hierarchicalContainer, itemId);
return hierarchicalContainer;
}
private void copyChildren(HierarchicalContainer source,
HierarchicalContainer target, Object itemId) {
Collection<?> children = source.getChildren(itemId);
if (children != null) {
for (Object childId : children) {
Item item = source.getItem(childId);
Item addedItem = target.addItem(childId);
target.setParent(childId, itemId);
Collection<?> itemPropertyIds = item
.getItemPropertyIds();
for (Object propertyId : itemPropertyIds) {
addedItem.getItemProperty(propertyId)
.setValue(
item.getItemProperty(propertyId)
.getValue());
}
copyChildren(source, target, childId);
}
}
}
@Override
public void drop(DragAndDropEvent event) {
TreeTargetDetails details = (TreeTargetDetails) event
.getTargetDetails();
// TODO set properties, so same sorter could be used in Table
Transferable transferable = event.getTransferable();
if (transferable instanceof DataBoundTransferable) {
DataBoundTransferable transferrable2 = (DataBoundTransferable) transferable;
Object itemId = transferrable2.getItemId();
Object itemIdOver = details.getItemIdOver();
// TODO could use the "folder" node id to make the drop
// logic simpler
Object itemIdInto = details.getItemIdInto();
VerticalDropLocation dropLocation = details
.getDropLocation();
Object itemIdAfter = details.getItemIdAfter();
if (itemIdOver.equals(itemIdInto)) { // directly on a node
t.setParent(itemId, itemIdOver);
return;
}
idx.setParent(itemId, itemIdInto);
if (dropLocation == null) {
System.err.println("No detail of drop place available");
}
idx.moveAfterSibling(itemId, itemIdAfter);
}
return;
}
@Override
public AcceptCriterion getAcceptCriterion() {
// TODO should actually check that source is same as target
return AcceptItem.ALL;
}
};
t.setDropHandler(itemSorter);
Table ta = new Table("Test table");
ta.setContainerDataSource(idx);
ta.addContainerProperty("Foos", String.class, "Foo");
ta.addContainerProperty("Bars", String.class, "Bar");