|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- ---
- title: Drag and Drop
- order: 12
- layout: page
- ---
-
- [[advanced.dragndrop]]
- = Drag and Drop
-
- ((("Drag and Drop", id="term.advanced.dragndrop", range="startofrange")))
-
-
- Dragging an object from one location to another by grabbing it with mouse,
- holding the mouse button pressed, and then releasing the button to "drop" it to
- the other location is a common way to move, copy, or associate objects. For
- example, most operating systems allow dragging and dropping files between
- folders or dragging a document on a program to open it. In Vaadin, it is
- possible to drag and drop components and parts of certain components.
-
- Dragged objects, or __transferables__, are essentially data objects. You can
- drag and drop rows in [classname]#Table# and nodes in [classname]#Tree#
- components, either within or between the components. You can also drag entire
- components by wrapping them inside [classname]#DragAndDropWrapper#.
-
- Dragging starts from a __drag source__, which defines the transferable.
- Transferables implement the [classname]#Transferable# interfaces. For trees and
- tables, which are bound to [classname]#Container# data sources, a node or row
- transferable is a reference to an [classname]#Item# in the Vaadin Data Model.
- Dragged components are referenced with a [classname]#WrapperTransferable#.
- Starting dragging does not require any client-server communication, you only
- need to enable dragging. All drag and drop logic occurs in two operations:
- determining ( __accepting__) where dropping is allowed and actually dropping.
- Drops can be done on a __drop target__, which implements the
- [classname]#DropTarget# interface. Three components implement the interface:
- [classname]#Tree#, [classname]#Table#, and [classname]#DragAndDropWrapper#.
- These accept and drop operations need to be provided in a __drop handler__.
- Essentially all you need to do to enable drag and drop is to enable dragging in
- the drag source and implement the [methodname]#getAcceptCriterion()# and
- [methodname]#drop()# methods in the [classname]#DropHandler# interface.
-
- The client-server architecture of Vaadin causes special requirements for the
- drag and drop functionality. The logic for determining where a dragged object
- can be dropped, that is, __accepting__ a drop, should normally be done on the
- client-side, in the browser. Server communications are too slow to have much of
- such logic on the server-side. The drag and drop feature therefore offers a
- number of ways to avoid the server communications to ensure a good user
- experience.
-
- [[advanced.dragndrop.drophandler]]
- == Handling Drops
-
- Most of the user-defined drag and drop logic occurs in a __drop handler__, which
- is provided by implementing the [methodname]#drop()# method in the
- [classname]#DropHandler# interface. A closely related definition is the drop
- accept criterion, which is defined in the [methodname]#getAcceptCriterion()#
- method in the same interface. It is described in
- <<advanced.dragndrop.acceptcriteria>> later.
-
- The [methodname]#drop()# method gets a [classname]#DragAndDropEvent# as its
- parameters. The event object provides references to two important object:
- [classname]#Transferable# and [classname]#TargetDetails#.
-
- A [classname]#Transferable# contains a reference to the object (component or
- data item) that is being dragged. A tree or table item is represented as a
- [classname]#TreeTransferable# or [classname]#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
- [classname]#DataBoundTransferable#. Dragged components are represented as
- [classname]#WrapperTransferable# objects, as the components are wrapped in a
- [classname]#DragAndDropWrapper#.
-
- The [classname]#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 [classname]#AbstractSelectTargetDetails#
- object tells the item on which the drop is being made. For trees, the
- [classname]#TreeTargetDetails# gives some more details. For wrapped components,
- the information is provided in a [classname]#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
- [methodname]#getDropLocation()# and for wrapped components with
- [methodname]#verticalDropLocation()# and [methodname]#horizontalDropLocation()#.
- The locations are specified as either [classname]#VerticalDropLocation# or
- [classname]#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 [classname]#Tree#, [classname]#Table#, and a wrapped component is
- explained further in the following sections.
-
-
- [[advanced.dragndrop.treedrop]]
- == Dropping Items On a [classname]#Tree#
-
- You can drag items from, to, or within a [classname]#Tree#. Making tree a drag
- source requires simply setting the drag mode with [methodname]#setDragMode()#.
- [classname]#Tree# currently supports only one drag mode,
- [literal]#++TreeDragMode.NODE++#, which allows dragging single tree nodes. While
- dragging, the dragged node is referenced with a [classname]#TreeTransferable#
- object, which is a [classname]#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
- [classname]#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
- [methodname]#getItemIdOver()# method in
- [classname]#AbstractSelectTargetDetails#, which the
- [classname]#TreeTargetDetails# inherits. A drop can occur directly on or above
- or below a node; the exact location is a [classname]#VerticalDropLocation#,
- which you can get with the [methodname]#getDropLocation()# method.
-
- In the example below, we have a [classname]#Tree# and we allow reordering the
- tree items by drag and drop.
-
-
- [source, java]
- ----
- 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();
-
- // 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);
- }
- }
- });
- ----
-
- [[advanced.dragndrop.treedrop.criteria]]
- === Accept Criteria for Trees
-
- [classname]#Tree# defines some specialized accept criteria for trees.
-
- [classname]#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 [literal]#++-1++# means infinite, that is, the entire sub-tree, and is therefore the same as the simpler constructor.
- [classname]#TargetItemAllowsChildren#(client-side):: Accepts a drop if the tree has [methodname]#setChildrenAllowed()# enabled for the target item. The criterion does not require parameters, so the class is a singleton and can be acquired with [methodname]#Tree.TargetItemAllowsChildren.get()#. For example, the following composite criterion accepts drops only on nodes that allow children, but between all nodes:
- +
- [source, java]
- ----
- return new Or (Tree.TargetItemAllowsChildren.get(), new Not(VerticalLocationIs.MIDDLE));
- ----
-
- [classname]#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 [methodname]#getAllowedItemIds()# to return the set. While the criterion is server-side, it is lazy-loading, so that the list of accepted target nodes is loaded only once from the server for each drag operation. See <<advanced.dragndrop.acceptcriteria>> for an example.
-
-
- In addition, the accept criteria defined in [classname]#AbstractSelect# are
- available for a [classname]#Tree#, as listed in
- <<advanced.dragndrop.acceptcriteria>>.
-
-
-
- [[advanced.dragndrop.tabledrop]]
- == Dropping Items On a [classname]#Table#
-
- You can drag items from, to, or within a [classname]#Table#. Making table a drag
- source requires simply setting the drag mode with [methodname]#setDragMode()#.
- [classname]#Table# supports dragging both single rows, with
- [literal]#++TableDragMode.ROW++#, and multiple rows, with
- [literal]#++TableDragMode.MULTIROW++#. While dragging, the dragged node or nodes
- are referenced with a [classname]#TreeTransferable# object, which is a
- [classname]#DataBoundTransferable#. Tree nodes are identified by the item IDs of
- the container items.
-
- When a transferable is dropped on a table, the drop location is stored in a
- [classname]#AbstractSelectTargetDetails# object, which identifies the target row
- by its item ID. You can get the item ID with [methodname]#getItemIdOver()#
- method. A drop can occur directly on or above or below a row; the exact location
- is a [classname]#VerticalDropLocation#, which you can get with the
- [methodname]#getDropLocation()# method from the details object.
-
- [[advanced.dragndrop.tabledrop.criteria]]
- === Accept Criteria for Tables
-
- [classname]#Table# defines one specialized accept criterion for tables.
-
- [classname]#TableDropCriterion#(server-side):: Accepts drops only on (or above or below) items that are specified by a set of item IDs. You must extend the abstract class and implement the [methodname]#getAllowedItemIds()# to return the set. While the criterion is server-side, it is lazy-loading, so that the list of accepted target items is loaded only once from the server for each drag operation.
-
-
-
-
- [[advanced.dragndrop.acceptcriteria]]
- == Accepting Drops
-
- ((("Drag and Drop", "Accept Criteria", id="term.advanced.dragndrop.acceptcriteria", range="startofrange")))
-
-
- You can not drop the objects you are dragging around just anywhere. Before a
- drop is possible, the specific drop location on which the mouse hovers must be
- __accepted__. Hovering a dragged object over an accepted location displays an
- __accept indicator__, which allows the user to position the drop properly. As
- such checks have to be done all the time when the mouse pointer moves around the
- drop targets, it is not feasible to send the accept requests to the server-side,
- so drops on a target are normally accepted by a client-side __accept
- criterion__.
-
- A drop handler must define the criterion on the objects which it accepts to be
- dropped on the target. The criterion needs to be provided in the
- [classname]#getAcceptCriterion()# method of the [classname]#DropHandler#
- interface. A criterion is represented in an [classname]#AcceptCriterion# object,
- which can be a composite of multiple criteria that are evaluated using logical
- operations. There are two basic types of criteria: __client-side__ and
- __server-side criteria__. The various built-in criteria allow accepting drops
- based on the identity of the source and target components, and on the __data
- flavor__ of the dragged objects.
-
- To allow dropping any transferable objects, you can return a universal accept
- criterion, which you can get with [methodname]#AcceptAll.get()#.
-
-
- [source, java]
- ----
- tree.setDropHandler(new DropHandler() {
- public AcceptCriterion getAcceptCriterion() {
- return AcceptAll.get();
- }
- ...
- ----
-
- [[advanced.dragndrop.acceptcriteria.client-side]]
- === Client-Side Criteria
-
- The __client-side criteria__, which inherit the
- [classname]#ClientSideCriterion#, are verified on the client-side, so server
- requests are not needed for verifying whether each component on which the mouse
- pointer hovers would accept a certain object.
-
- The following client-side criteria are define in
- [package]#com.vaadin.event.dd.acceptcriterion#:
-
- [classname]#AcceptAll#:: Accepts all transferables and targets.
- [classname]#And#:: Performs the logical AND operation on two or more client-side criteria; accepts the transferable if all the given sub-criteria accept it.
- [classname]#ContainsDataFlavour#:: The transferable must contain the defined data flavour.
- [classname]#Not#:: Performs the logical NOT operation on a client-side criterion; accepts the transferable if and only if the sub-criterion does not accept it.
- [classname]#Or#:: Performs the logical OR operation on two or more client-side criteria; accepts the transferable if any of the given sub-criteria accepts it.
- [classname]#SourceIs#:: Accepts all transferables from any of the given source components
- [classname]#SourceIsTarget#:: Accepts the transferable only if the source component is the same as the target. This criterion is useful for ensuring that items are dragged only within a tree or a table, and not from outside it.
- [classname]#TargetDetailIs#:: Accepts any transferable if the target detail, such as the item of a tree node or table row, is of the given data flavor and has the given value.
-
-
- In addition, target components such as [classname]#Tree# and [classname]#Table#
- define some component-specific client-side accept criteria. See
- <<advanced.dragndrop.treedrop>> for more details.
-
- [classname]#AbstractSelect# defines the following criteria for all selection
- components, including [classname]#Tree# and [classname]#Table#.
-
- [classname]#AcceptItem#:: Accepts only specific items from a specific selection component. The selection component, which must inherit [classname]#AbstractSelect#, is given as the first parameter for the constructor. It is followed by a list of allowed item identifiers in the drag source.
- [classname]#AcceptItem.ALL#:: Accepts all transferables as long as they are items.
- [classname]#TargetItemIs#:: Accepts all drops on the specified target items. The constructor requires the target component ( [classname]#AbstractSelect#) followed by a list of allowed item identifiers.
- [classname]#VerticalLocationIs.MIDDLE#,[classname]#TOP#, and[classname]#BOTTOM#:: The three static criteria accepts drops on, above, or below an item. For example, you could accept drops only in between items with the following:
- [source, java]
- ----
- public AcceptCriterion getAcceptCriterion() {
- return new Not(VerticalLocationIs.MIDDLE);
- }
- ----
-
-
-
-
-
- [[advanced.dragndrop.acceptcriteria.server-side]]
- === Server-Side Criteria
-
- The __server-side criteria__ are verified on the server-side with the
- [methodname]#accept()# method of the [classname]#ServerSideCriterion# class.
- This allows fully programmable logic for accepting drops, but the negative side
- is that it causes a very large amount of server requests. A request is made for
- every target position on which the pointer hovers. This problem is eased in many
- cases by the component-specific lazy loading criteria
- [classname]#TableDropCriterion# and [classname]#TreeDropCriterion#. They do the
- server visit once for each drag and drop operation and return all accepted rows
- or nodes for current [classname]#Transferable# at once.
-
- The [methodname]#accept()# method gets the drag event as a parameter so it can
- perform its logic much like in [methodname]#drop()#.
-
-
- [source, java]
- ----
- public AcceptCriterion getAcceptCriterion() {
- // Server-side accept criterion that allows drops on any other
- // location except on nodes that may not have children
- ServerSideCriterion criterion = new ServerSideCriterion() {
- public boolean accept(DragAndDropEvent dragEvent) {
- TreeTargetDetails target = (TreeTargetDetails)
- dragEvent.getTargetDetails();
-
- // The tree item on which the load hovers
- Object targetItemId = target.getItemIdOver();
-
- // On which side of the target the item is hovered
- VerticalDropLocation location = target.getDropLocation();
- if (location == VerticalDropLocation.MIDDLE)
- if (! tree.areChildrenAllowed(targetItemId))
- return false; // Not accepted
-
- return true; // Accept everything else
- }
- };
- return criterion;
- }
- ----
-
- The server-side criteria base class [classname]#ServerSideCriterion# provides a
- generic [methodname]#accept()# method. The more specific
- [classname]#TableDropCriterion# and [classname]#TreeDropCriterion# are
- conveniency extensions that allow definiting allowed drop targets as a set of
- items. They also provide some optimization by lazy loading, which reduces server
- communications significantly.
-
-
- [source, java]
- ----
- public AcceptCriterion getAcceptCriterion() {
- // Server-side accept criterion that allows drops on any
- // other tree node except on node that may not have children
- TreeDropCriterion criterion = new TreeDropCriterion() {
- @Override
- protected Set<Object> getAllowedItemIds(
- DragAndDropEvent dragEvent, Tree tree) {
- HashSet<Object> allowed = new HashSet<Object>();
- for (Iterator<Object> i =
- tree.getItemIds().iterator(); i.hasNext();) {
- Object itemId = i.next();
- if (tree.hasChildren(itemId))
- allowed.add(itemId);
- }
- return allowed;
- }
- };
- return criterion;
- }
- ----
-
-
- [[advanced.dragndrop.acceptcriteria.indicators]]
- === Accept Indicators
-
- When a dragged object hovers on a drop target, an __accept indicator__ is
- displayed to show whether or not the location is accepted. For
- [parameter]#MIDDLE# location, the indicator is a box around the target (tree
- node, table row, or component). For vertical drop locations, the accepted
- locations are shown as horizontal lines, and for horizontal drop locations as
- vertical lines.
-
- For [classname]#DragAndDropWrapper# drop targets, you can disable the accept
- indicators or __drag hints__ with the [parameter]#no-vertical-drag-hints#,
- [parameter]#no-horizontal-drag-hints#, and [parameter]#no-box-drag-hints#
- styles. You need to add the styles to the __layout that contains__ the wrapper,
- not to the wrapper itself.
-
-
- [source, java]
- ----
- // Have a wrapper
- DragAndDropWrapper wrapper = new DragAndDropWrapper(c);
- layout.addComponent(wrapper);
-
- // Disable the hints
- layout.addStyleName("no-vertical-drag-hints");
- layout.addStyleName("no-horizontal-drag-hints");
- layout.addStyleName("no-box-drag-hints");
- ----
-
-
- (((range="endofrange", startref="term.advanced.dragndrop.acceptcriteria")))
-
- [[advanced.dragndrop.dragging]]
- == Dragging Components
-
- Dragging a component requires wrapping the source component within a
- [classname]#DragAndDropWrapper#. You can then allow dragging by putting the
- wrapper (and the component) in drag mode with [methodname]#setDragStartMode()#.
- The method supports two drag modes: [parameter]#DragStartMode.WRAPPER# and
- [parameter]#DragStartMode.COMPONENT#, which defines whether the entire wrapper
- is shown as the drag image while dragging or just the wrapped component.
-
-
- [source, java]
- ----
- // Have a component to drag
- final Button button = new Button("An Absolute Button");
-
- // Put the component in a D&D wrapper and allow dragging it
- final DragAndDropWrapper buttonWrap = new DragAndDropWrapper(button);
- buttonWrap.setDragStartMode(DragStartMode.COMPONENT);
-
- // Set the wrapper to wrap tightly around the component
- buttonWrap.setSizeUndefined();
-
- // Add the wrapper, not the component, to the layout
- layout.addComponent(buttonWrap, "left: 50px; top: 50px;");
- ----
-
- The default height of [classname]#DragAndDropWrapper# is undefined, but the
- default width is 100%. If you want to ensure that the wrapper fits tightly
- around the wrapped component, you should call [methodname]#setSizeUndefined()#
- for the wrapper. Doing so, you should make sure that the wrapped component does
- not have a relative size, which would cause a paradox.
-
- Dragged components are referenced in the [classname]#WrapperTransferable#. You
- can get the reference to the dragged component with
- [methodname]#getDraggedComponent()#. The method will return [literal]#++null++#
- if the transferable is not a component. Also HTML 5 drags (see later) are held
- in wrapper transferables.
-
-
- [[advanced.dragndrop.drop-on-component]]
- == Dropping on a Component
-
- Drops on a component are enabled by wrapping the component in a
- [classname]#DragAndDropWrapper#. The wrapper is an ordinary component; the
- constructor takes the wrapped component as a parameter. You just need to define
- the [classname]#DropHandler# for the wrapper with
- [methodname]#setDropHandler()#.
-
- In the following example, we allow moving components in an absolute layout.
- Details on the drop handler are given later.
-
-
- [source, java]
- ----
- // A layout that allows moving its contained components
- // by dragging and dropping them
- final AbsoluteLayout absLayout = new AbsoluteLayout();
- absLayout.setWidth("100%");
- absLayout.setHeight("400px");
-
- ... put some (wrapped) components in the layout ...
-
- // Wrap the layout to allow handling drops
- DragAndDropWrapper layoutWrapper =
- new DragAndDropWrapper(absLayout);
-
- // Handle moving components within the AbsoluteLayout
- layoutWrapper.setDropHandler(new DropHandler() {
- public AcceptCriterion getAcceptCriterion() {
- return AcceptAll.get();
- }
-
- public void drop(DragAndDropEvent event) {
- ...
- }
- });
- ----
-
- [[advanced.dragndrop.drop-on-component.details]]
- === Target Details for Wrapped Components
-
- The drop handler receives the drop target details in a
- [classname]#WrapperTargetDetails# object, which implements the
- [classname]#TargetDetails# interface.
-
-
- [source, java]
- ----
- public void drop(DragAndDropEvent event) {
- WrapperTransferable t =
- (WrapperTransferable) event.getTransferable();
- WrapperTargetDetails details =
- (WrapperTargetDetails) event.getTargetDetails();
- ----
-
- The wrapper target details include a [classname]#MouseEventDetails# object,
- which you can get with [methodname]#getMouseEvent()#. You can use it to get the
- mouse coordinates for the position where the mouse button was released and the
- drag ended. Similarly, you can find out the drag start position from the
- transferable object (if it is a [classname]#WrapperTransferable#) with
- [methodname]#getMouseDownEvent()#.
-
-
- [source, java]
- ----
- // Calculate the drag coordinate difference
- int xChange = details.getMouseEvent().getClientX()
- - t.getMouseDownEvent().getClientX();
- int yChange = details.getMouseEvent().getClientY()
- - t.getMouseDownEvent().getClientY();
-
- // Move the component in the absolute layout
- ComponentPosition pos =
- absLayout.getPosition(t.getSourceComponent());
- pos.setLeftValue(pos.getLeftValue() + xChange);
- pos.setTopValue(pos.getTopValue() + yChange);
- ----
-
- You can get the absolute x and y coordinates of the target wrapper with
- [methodname]#getAbsoluteLeft()# and [methodname]#getAbsoluteTop()#, which allows
- you to translate the absolute mouse coordinates to coordinates relative to the
- wrapper. Notice that the coordinates are really the position of the wrapper, not
- the wrapped component; the wrapper reserves some space for the accept
- indicators.
-
- The [methodname]#verticalDropLocation()# and
- [methodname]#horizontalDropLocation()# return the more detailed drop location in
- the target.
-
-
-
- [[advanced.dragndrop.external]]
- == Dragging Files from Outside the Browser
-
- The [classname]#DragAndDropWrapper# allows dragging files from outside the
- browser and dropping them on a component wrapped in the wrapper. Dropped files
- are automatically uploaded to the application and can be acquired from the
- wrapper with [methodname]#getFiles()#. The files are represented as
- [classname]#Html5File# objects as defined in the inner class. You can define an
- upload [classname]#Receiver# to receive the content of a file to an
- [classname]#OutputStream#.
-
- Dragging and dropping files to browser is supported in HTML 5 and requires a
- compatible browser, such as Mozilla Firefox 3.6 or newer.
-
-
- (((range="endofrange", startref="term.advanced.dragndrop")))
-
-
|