Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
book-of-vaadin.pdf
Скачиваний:
88
Добавлен:
24.03.2015
Размер:
13.43 Mб
Скачать

Advanced Web Application Topics

A Transferable contains a reference to the object (component or data item) that is being dragged. A tree or table item is represented as a TreeTransferable or TableTransferable object, which carries the item identifier of the dragged tree or table item. These special transferables, which are bound to some data in a container, are DataBoundTransferable. Dragged components are represented as WrapperTransferable objects, as the components are wrapped in a DragAndDropWrapper.

The TargetDetails object provides information about the exact location where the transferable object is being dropped. The exact class of the details object depends on the drop target and you need to cast it to the proper subclass to get more detailed information. If the target is selection component, essentially a tree or a table, the AbstractSelectTargetDetails object tells the item on which the drop is being made. For trees, the TreeTargetDetails gives some more details. For wrapped components, the information is provided in a WrapperDropDetails object. In addition to the target item or component, the details objects provide a drop location. For selection components, the location can be obtained with the getDropLocation() and for wrapped components with verticalDropLocation() and horizontalDropLocation(). The locations are specified as either VerticalDropLocation or HorizontalDropLocation objects. The drop location objects specify whether the transferable is being dropped above, below, or directly on (at the middle of) a component or item.

Dropping on a Tree, Table, and a wrapped component is explained further in the following sections.

11.11.2. Dropping Items On a Tree

You can drag items from, to, or within a Tree. Making tree a drag source requires simply setting the drag mode with setDragMode(). Tree currently supports only one drag mode, TreeDragMode.NODE, which allows dragging single tree nodes. While dragging, the dragged node is referenced with a TreeTransferable object, which is a DataBoundTransferable. The tree node is identified by the item ID of the container item.

When a transferable is dropped on a tree, the drop location is stored in a TreeTargetDetails object, which identifies the target location by item ID of the tree node on which the drop is made. You can get the item ID with getItemIdOver() method in AbstractSelectTargetDetails, which the TreeTargetDetails inherits. A drop can occur directly on or above or below a node; the exact location is a VerticalDropLocation, which you can get with the getDropLocation() method.

In the example below, we have a Tree and we allow reordering the tree items by drag and drop.

final Tree tree = new Tree("Inventory"); tree.setContainerDataSource(TreeExample.createTreeContent()); layout.addComponent(tree);

// Expand all items

for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) tree.expandItemsRecursively(it.next());

//Set the tree in drag source mode tree.setDragMode(TreeDragMode.NODE);

//Allow the tree to receive drag drops and handle them tree.setDropHandler(new DropHandler() {

public AcceptCriterion getAcceptCriterion() { return AcceptAll.get();

}

public void drop(DragAndDropEvent event) {

// Wrapper for the object that is dragged Transferable t = event.getTransferable();

Dropping Items On a Tree

305

Advanced Web Application Topics

// Make sure the drag source is the same tree if (t.getSourceComponent() != tree)

return;

TreeTargetDetails target = (TreeTargetDetails) event.getTargetDetails();

//Get ids of the dragged item and the target item Object sourceItemId = t.getData("itemId");

Object targetItemId = target.getItemIdOver();

//On which side of the target the item was dropped VerticalDropLocation location = target.getDropLocation();

HierarchicalContainer container = (HierarchicalContainer) tree.getContainerDataSource();

//Drop right on an item -> make it a child if (location == VerticalDropLocation.MIDDLE)

tree.setParent(sourceItemId, targetItemId);

//Drop at the top of a subtree -> make it previous else if (location == VerticalDropLocation.TOP) {

Object parentId = container.getParent(targetItemId); container.setParent(sourceItemId, parentId); container.moveAfterSibling(sourceItemId, targetItemId); container.moveAfterSibling(targetItemId, sourceItemId);

}

//Drop below another item -> make it next

else if (location == VerticalDropLocation.BOTTOM) { Object parentId = container.getParent(targetItemId); container.setParent(sourceItemId, parentId);

container.moveAfterSibling(sourceItemId, targetItemId);

}

}

});

Accept Criteria for Trees

Tree defines some specialized accept criteria for trees.

TargetInSubtree (client-side)

Accepts if the target item is in the specified sub-tree. The sub-tree is specified by the item ID of the root of the sub-tree in the constructor. The second constructor includes a depth parameter, which specifies how deep from the given root node are drops accepted. Value -1 means infinite, that is, the entire sub-tree, and is therefore the same as the simpler constructor.

TargetItemAllowsChildren (client-side)

Accepts a drop if the tree has setChildrenAllowed() enabled for the target item. The criterion does not require parameters, so the class is a singleton and can be acquired with Tree.TargetItemAllowsChildren.get(). For example, the following composite criterion accepts drops only on nodes that allow children, but between all nodes:

return new Or (Tree.TargetItemAllowsChildren.get(), new

Not(VerticalLocationIs.MIDDLE));

TreeDropCriterion (server-side)

Accepts drops on only some items, which as specified by a set of item IDs. You must extend the abstract class and implement the getAllowedItemIds() to return the

306

Dropping Items On a Tree

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]