private Tree tree3;
@Override
protected void setup() {
UI w = getLayout().getUI();
/* darn reindeer has no icons */
/* Make all trees (their nodes actually) draggable */
tree1.setDragMode(TreeDragMode.NODE);
tree2.setDragMode(TreeDragMode.NODE);
hl.addComponent(tree1);
hl.addComponent(table);
hl.addComponent(tree2);
hl.setWidth("100%");
hl.setSpacing(true);
hl.setExpandRatio(table, 1);
popuplateTrees();
table.setWidth("100%");
table.setPageLength(10);
populateTable();
addComponent(hl);
tree3 = new Tree(
"Tree with lazy loading criteria, of first server visit caches accept rules for all captions");
tree3.setDragMode(TreeDragMode.NODE);
tree3.addItem("Drag on me");
tree3.addItem("Or me");
/*
* An example of lazy initializing drop criterion with component
* specific api for easy rule writing.
*
* Example is pretty stupid (accepts drop on all nodes, but by
* explicitly defining them here), but demonstrates lazy initialization
* option if rules are heavy.
*/
final AcceptCriterion crit = new Tree.TreeDropCriterion() {
@Override
protected Set<Object> getAllowedItemIds(DragAndDropEvent dragEvent,
Tree tree) {
return new HashSet<Object>(tree.getItemIds());
}
};
tree3.setDropHandler(new DropHandler() {
@Override
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) {
Collection<?> children = tree1.getChildren(itemId);
if (children != null) {
for (Object childId : children) {
Object newItemId = tree2.addItem();
tree2.setItemCaption(newItemId, (String) childId);
tree2.setParent(newItemId, itemIdTo);
copySubTree(childId, newItemId);
}
}
}
@Override
public AcceptCriterion getAcceptCriterion() {
return AcceptItem.ALL;
}
};
tree2.setDropHandler(dropHandler);
/*
* Finally add two windows with DragDropPane. First accept anything,
* second has server side accept rule to allow only drops from Tree1.
* Check the code in implementing classes.
*/
Window acceptAnyThing = new AcceptAnythingWindow();
Window acceptFromTree1viaServerCheck = new AcceptFromComponent(tree1);
w.addWindow(acceptAnyThing);
acceptAnyThing.setPositionY(450);
acceptAnyThing.setPositionX(150);
w.addWindow(acceptFromTree1viaServerCheck);
acceptFromTree1viaServerCheck.setPositionY(450);
acceptFromTree1viaServerCheck.setPositionX(450);
}