public void drop(DragAndDropEvent dropEvent) {
Transferable transferable = dropEvent.getTransferable();
String data = (String) transferable.getData("Text");
if (transferable instanceof TableTransferable) {
TableTransferable tr = (TableTransferable) transferable;
System.out.println("From table row" + tr.getPropertyId());
Object value = tr.getSourceContainer()
.getItem(tr.getItemId())
.getItemProperty(tr.getPropertyId()).getValue();
data = (null != value) ? value.toString() : null;
}
if (data == null) {
data = "-no Text data flavor-";
}
tree3.addItem(data);
AbstractSelect.AbstractSelectTargetDetails dropTargetData = (AbstractSelect.AbstractSelectTargetDetails) dropEvent
.getTargetDetails();
tree3.setParent(data, dropTargetData.getItemIdOver());
}
@Override
public AcceptCriterion getAcceptCriterion() {
return crit;
}
});
addComponent(tree3);
/*
* Make table rows draggable
*/
table.setDragMode(Table.TableDragMode.ROW);
TargetItemAllowsChildren onNode = TargetItemAllowsChildren.get();
SourceIs fromTable = new SourceIs(table);
SourceIs fromTree = new SourceIs(tree1);
final Or fromTree1OrTable = new Or(fromTable, fromTree);
// Or could in the case be replaced with, keeping here as an example and
// test
@SuppressWarnings("unused")
SourceIs treeOrTable = new SourceIs(table, tree1);
final And and = new And(fromTree1OrTable, onNode);
DropHandler dropHandler = new DropHandler() {
@Override
public void drop(DragAndDropEvent event) {
/*
* We know transferrable is from table, so it is of type
* DataBoundTransferrable
*/
DataBoundTransferable tr = (DataBoundTransferable) event
.getTransferable();
Object itemId = tr.getItemId();
Container sourceContainer = tr.getSourceContainer();
if (tr.getSourceComponent() != tree1) {
// if the source is from table (not from tree1 itself),
// transfer Name property and use it as an identifier in
// tree1
Object nameValue = sourceContainer.getItem(itemId)
.getItemProperty("Name").getValue();
String name = (null != nameValue) ? nameValue.toString()
: null;
tree1.addItem(name);
tree1.setChildrenAllowed(name, false);
/*
* Remove the item from table
*/
sourceContainer.removeItem(itemId);
itemId = name;
}
/*
* As we also accept only drops on folders, we know dropDetails
* is from Tree and it contains itemIdOver.
*/
AbstractSelectTargetDetails details = (AbstractSelectTargetDetails) event
.getTargetDetails();
Object idOver = details.getItemIdOver();
tree1.setParent(itemId, idOver);
}
@Override
public AcceptCriterion getAcceptCriterion() {
return and;
}
};
tree1.setDropHandler(dropHandler);
/*
* First step done. tree1 now accepts drags only from table and only
* over tree nodes aka "folders"
*/
/*
* Now set the rightmost tree accept any item drag. On drop, copy from
* source. Also make drags from tree1 possible.
*/
dropHandler = new DropHandler() {
@Override
public void drop(DragAndDropEvent event) {
AbstractSelectTargetDetails details = (AbstractSelectTargetDetails) event
.getTargetDetails();
Transferable transferable = event.getTransferable();
if (transferable instanceof DataBoundTransferable) {
DataBoundTransferable tr = (DataBoundTransferable) transferable;
Object itemId = tree2.addItem();
tree2.setParent(itemId, details.getItemIdOver());
if (tr.getSourceComponent() == tree1) {
// use item id from tree1 as caption
tree2.setItemCaption(itemId, (String) tr.getItemId());
// if comes from tree1, move subtree too
copySubTree(tr.getItemId(), itemId);
} else if (tr.getSourceComponent() == table) {
// comes from table, override caption with name
String name = (String) table.getItem(tr.getItemId())
.getItemProperty("Name").getValue();
tree2.setItemCaption(itemId, name);
} else if (tr.getSourceComponent() == tree2) {
tree2.setItemCaption(itemId,
tree2.getItemCaption(tr.getItemId()));
}
}
}
private void copySubTree(Object itemId, Object itemIdTo) {