You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

TreeDragStart.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330
  1. package com.vaadin.tests.dd;
  2. import java.io.Serializable;
  3. import java.util.ArrayList;
  4. import java.util.HashMap;
  5. import java.util.Iterator;
  6. import com.vaadin.data.Container;
  7. import com.vaadin.data.Property.ValueChangeEvent;
  8. import com.vaadin.data.Property.ValueChangeListener;
  9. import com.vaadin.data.util.BeanItem;
  10. import com.vaadin.data.util.BeanItemContainer;
  11. import com.vaadin.data.util.HierarchicalContainer;
  12. import com.vaadin.event.DataBoundTransferable;
  13. import com.vaadin.event.dd.DragAndDropEvent;
  14. import com.vaadin.event.dd.DropHandler;
  15. import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
  16. import com.vaadin.event.dd.acceptcriteria.Not;
  17. import com.vaadin.event.dd.acceptcriteria.Or;
  18. import com.vaadin.shared.ui.dd.VerticalDropLocation;
  19. import com.vaadin.tests.components.TestBase;
  20. import com.vaadin.ui.AbstractSelect.AbstractSelectTargetDetails;
  21. import com.vaadin.ui.AbstractSelect.VerticalLocationIs;
  22. import com.vaadin.ui.CheckBox;
  23. import com.vaadin.ui.Table;
  24. import com.vaadin.ui.Table.TableDragMode;
  25. import com.vaadin.ui.Tree;
  26. import com.vaadin.ui.Tree.TreeDragMode;
  27. import com.vaadin.ui.Tree.TreeTargetDetails;
  28. public class TreeDragStart extends TestBase {
  29. @Override
  30. protected void setup() {
  31. final Tree tree = new Tree("Inventory");
  32. CheckBox checkBox = new CheckBox("Enabled");
  33. checkBox.setImmediate(true);
  34. checkBox.setValue(true);
  35. checkBox.addListener(new ValueChangeListener() {
  36. @Override
  37. public void valueChange(ValueChangeEvent event) {
  38. tree.setEnabled(!tree.isEnabled());
  39. }
  40. });
  41. addComponent(checkBox);
  42. checkBox = new CheckBox("Drag start");
  43. checkBox.setImmediate(true);
  44. checkBox.setValue(true);
  45. checkBox.addListener(new ValueChangeListener() {
  46. @Override
  47. public void valueChange(ValueChangeEvent event) {
  48. if (((CheckBox) event.getProperty()).getValue()) {
  49. tree.setDragMode(TreeDragMode.NODE);
  50. } else {
  51. tree.setDragMode(TreeDragMode.NONE);
  52. }
  53. }
  54. });
  55. addComponent(checkBox);
  56. tree.setContainerDataSource(createTreeContent());
  57. tree.setItemCaptionMode(Tree.ITEM_CAPTION_MODE_EXPLICIT_DEFAULTS_ID);
  58. for (Object item : tree.getItemIds().toArray()) {
  59. tree.setItemCaption(item, (String) ((BeanItem<?>) item)
  60. .getItemProperty("name").getValue());
  61. }
  62. getLayout().addComponent(tree);
  63. // Expand all items
  64. for (Iterator<?> it = tree.rootItemIds().iterator(); it.hasNext();) {
  65. tree.expandItemsRecursively(it.next());
  66. }
  67. // Set the tree in drag source mode
  68. tree.setDragMode(TreeDragMode.NODE);
  69. // Allow the tree to receive drag drops and handle them
  70. tree.setDropHandler(new DropHandler() {
  71. @Override
  72. public AcceptCriterion getAcceptCriterion() {
  73. // Accept drops in the middle of container items
  74. // and below and above all items.
  75. return new Or(Tree.TargetItemAllowsChildren.get(), new Not(
  76. VerticalLocationIs.MIDDLE));
  77. }
  78. @Override
  79. public void drop(DragAndDropEvent event) {
  80. // Wrapper for the object that is dragged
  81. DataBoundTransferable t = (DataBoundTransferable) event
  82. .getTransferable();
  83. TreeTargetDetails target = (TreeTargetDetails) event
  84. .getTargetDetails();
  85. // Get ids of the dragged item and the target item
  86. Object sourceItemId = t.getData("itemId");
  87. Object targetItemId = target.getItemIdOver();
  88. // On which side of the target the item was dropped
  89. VerticalDropLocation location = target.getDropLocation();
  90. HierarchicalContainer container = (HierarchicalContainer) tree
  91. .getContainerDataSource();
  92. BeanItem<?> beanItem = null;
  93. if (sourceItemId instanceof BeanItem<?>) {
  94. beanItem = (BeanItem<?>) sourceItemId;
  95. } else if (sourceItemId instanceof InventoryObject) {
  96. beanItem = new BeanItem<InventoryObject>(
  97. (InventoryObject) sourceItemId);
  98. }
  99. // Remove the item from the source container and
  100. // add it to the tree's container
  101. Container sourceContainer = t.getSourceContainer();
  102. sourceContainer.removeItem(sourceItemId);
  103. tree.addItem(beanItem);
  104. InventoryObject bean = (InventoryObject) beanItem.getBean();
  105. tree.setChildrenAllowed(beanItem, bean.isContainer());
  106. // Drop right on an item -> make it a child
  107. if (location == VerticalDropLocation.MIDDLE) {
  108. tree.setParent(beanItem, targetItemId);
  109. } else if (location == VerticalDropLocation.TOP) {
  110. Object parentId = container.getParent(targetItemId);
  111. tree.setParent(beanItem, parentId);
  112. container.moveAfterSibling(beanItem, targetItemId);
  113. container.moveAfterSibling(targetItemId, beanItem);
  114. }
  115. // Drop below another item -> make it next
  116. else if (location == VerticalDropLocation.BOTTOM) {
  117. Object parentId = container.getParent(targetItemId);
  118. tree.setParent(beanItem, parentId);
  119. container.moveAfterSibling(beanItem, targetItemId);
  120. }
  121. tree.setItemCaption(beanItem, bean.getName());
  122. }
  123. });
  124. // Have a table that allows dragging from
  125. final Table table = new Table("Inventory List");
  126. table.setDragMode(TableDragMode.ROW);
  127. // Initialize the table container
  128. ArrayList<InventoryObject> collection = new ArrayList<InventoryObject>();
  129. collection.add(new InventoryObject("Dummy Item", 0.0, false));
  130. final BeanItemContainer<InventoryObject> tableContainer = new BeanItemContainer<InventoryObject>(
  131. collection);
  132. table.setContainerDataSource(tableContainer);
  133. table.setVisibleColumns(new String[] { "name", "weight" });
  134. table.removeAllItems();
  135. // Allow the table to receive drops and handle them
  136. table.setDropHandler(new DropHandler() {
  137. @Override
  138. public AcceptCriterion getAcceptCriterion() {
  139. return new Not(VerticalLocationIs.MIDDLE);
  140. }
  141. @Override
  142. public void drop(DragAndDropEvent event) {
  143. // Wrapper for the object that is dragged
  144. DataBoundTransferable t = (DataBoundTransferable) event
  145. .getTransferable();
  146. // Make sure the drag source is the same tree
  147. if (t.getSourceComponent() != tree
  148. && t.getSourceComponent() != table) {
  149. return;
  150. }
  151. AbstractSelectTargetDetails target = (AbstractSelectTargetDetails) event
  152. .getTargetDetails();
  153. // Get ids of the dragged item and the target item
  154. Object sourceItemId = t.getData("itemId");
  155. Object targetItemId = target.getItemIdOver();
  156. // Do not allow drop on the item itself
  157. if (sourceItemId.equals(targetItemId)) {
  158. return;
  159. }
  160. InventoryObject bean = null;
  161. if (sourceItemId instanceof BeanItem<?>) {
  162. bean = (InventoryObject) ((BeanItem<?>) sourceItemId)
  163. .getBean();
  164. } else if (sourceItemId instanceof InventoryObject) {
  165. bean = (InventoryObject) sourceItemId;
  166. }
  167. // Remove the item from the source container
  168. t.getSourceContainer().removeItem(sourceItemId);
  169. // On which side of the target the item was dropped
  170. VerticalDropLocation location = target.getDropLocation();
  171. // The table was empty or otherwise not on an item
  172. if (targetItemId == null) {
  173. tableContainer.addItem(bean); // Add to the end
  174. } else if (location == VerticalDropLocation.TOP) {
  175. tableContainer.addItemAt(
  176. tableContainer.indexOfId(targetItemId), bean);
  177. } else if (location == VerticalDropLocation.BOTTOM) {
  178. tableContainer.addItemAfter(targetItemId, bean);
  179. }
  180. }
  181. });
  182. getLayout().addComponent(table);
  183. }
  184. public class InventoryObject implements Serializable {
  185. private static final long serialVersionUID = -8943498783302996516L;
  186. String name;
  187. double weight;
  188. boolean container;
  189. public InventoryObject(String name, double weight, boolean container) {
  190. this.name = name;
  191. this.weight = weight;
  192. this.container = container;
  193. }
  194. public String getName() {
  195. return name;
  196. }
  197. public void setName(String name) {
  198. this.name = name;
  199. }
  200. public double getWeight() {
  201. return weight;
  202. }
  203. public void setWeight(double weight) {
  204. this.weight = weight;
  205. }
  206. public boolean isContainer() {
  207. return container;
  208. }
  209. public void setContainer(boolean container) {
  210. this.container = container;
  211. }
  212. }
  213. HashMap<String, InventoryObject> inventoryStore = new HashMap<String, InventoryObject>();
  214. public HierarchicalContainer createTreeContent() {
  215. final Object[] inventory = new Object[] {
  216. new InventoryObject("root", 0.0, true),
  217. new InventoryObject("+5 Quarterstaff (blessed)", 3.5, false),
  218. new InventoryObject("+3 Elven Dagger (blessed)", 0.2, false),
  219. new InventoryObject("+5 Helmet (greased)", 1.5, false),
  220. new Object[] {
  221. new InventoryObject("Sack", 0.2, true),
  222. new InventoryObject("Pick-Axe", 2.5, false),
  223. new InventoryObject("Lock Pick", 0.1, false),
  224. new InventoryObject("Tinning Kit", 0.5, false),
  225. new InventoryObject("Potion of Healing (blessed)", 0.7,
  226. false), },
  227. new Object[] {
  228. new InventoryObject("Bag of Holding", 0.1, true),
  229. new InventoryObject("Magic Marker", 0.05, false),
  230. new InventoryObject("Can of Grease (blessed)", 0.5,
  231. false), },
  232. new Object[] {
  233. new InventoryObject("Chest", 10.0, true),
  234. new InventoryObject("Scroll of Identify", 0.1, false),
  235. new InventoryObject("Scroll of Genocide", 0.1, false),
  236. new InventoryObject("Towel", 0.3, false),
  237. new Object[] {
  238. new InventoryObject("Large Box", 8.0, true),
  239. new InventoryObject("Figurine of Vaadin", 0.4,
  240. false),
  241. new InventoryObject("Expensive Camera", 1.5,
  242. false), },
  243. new InventoryObject("Tin Opener", 0.02, false), }, };
  244. HierarchicalContainer container = new HierarchicalContainer();
  245. new Object() {
  246. public void put(Object[] data, Object parent,
  247. HierarchicalContainer container) {
  248. for (int i = 1; i < data.length; i++) {
  249. BeanItem<InventoryObject> item;
  250. if (data[i].getClass() == InventoryObject.class) {
  251. InventoryObject object = (InventoryObject) data[i];
  252. item = new BeanItem<InventoryObject>(object);
  253. container.addItem(item);
  254. container.setParent(item, parent);
  255. container.setChildrenAllowed(item, false);
  256. } else {// It's an Object[]
  257. Object[] sub = (Object[]) data[i];
  258. InventoryObject object = (InventoryObject) sub[0];
  259. item = new BeanItem<InventoryObject>(object);
  260. container.addItem(item);
  261. container.setParent(item, parent);
  262. // Add children recursively
  263. put(sub, item, container);
  264. }
  265. inventoryStore
  266. .put(item.getBean().getName(), item.getBean());
  267. }
  268. }
  269. }.put(inventory, null, container);
  270. return container;
  271. }
  272. @Override
  273. protected String getDescription() {
  274. return "Should work";
  275. }
  276. @Override
  277. protected Integer getTicketNumber() {
  278. return 6320;
  279. }
  280. }