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.

GridDragAndDrop.java 8.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tests.components.grid;
  17. import java.util.Arrays;
  18. import java.util.List;
  19. import java.util.Random;
  20. import java.util.Set;
  21. import java.util.stream.Collectors;
  22. import java.util.stream.Stream;
  23. import com.vaadin.annotations.Theme;
  24. import com.vaadin.annotations.Widgetset;
  25. import com.vaadin.data.provider.ListDataProvider;
  26. import com.vaadin.server.VaadinRequest;
  27. import com.vaadin.shared.ui.dnd.DropEffect;
  28. import com.vaadin.shared.ui.dnd.EffectAllowed;
  29. import com.vaadin.shared.ui.grid.DropLocation;
  30. import com.vaadin.shared.ui.grid.DropMode;
  31. import com.vaadin.tests.components.AbstractTestUIWithLog;
  32. import com.vaadin.tests.util.Person;
  33. import com.vaadin.tests.util.TestDataGenerator;
  34. import com.vaadin.ui.Grid;
  35. import com.vaadin.ui.HorizontalLayout;
  36. import com.vaadin.ui.Layout;
  37. import com.vaadin.ui.RadioButtonGroup;
  38. import com.vaadin.ui.components.grid.GridDragSource;
  39. import com.vaadin.ui.components.grid.GridDropTarget;
  40. @Theme("valo")
  41. @Widgetset("com.vaadin.DefaultWidgetSet")
  42. public class GridDragAndDrop extends AbstractTestUIWithLog {
  43. private Set<Person> draggedItems;
  44. @Override
  45. protected void setup(VaadinRequest request) {
  46. getUI().setMobileHtml5DndEnabled(true);
  47. // Drag source Grid
  48. Grid<Person> left = createGridAndFillWithData(50);
  49. GridDragSource<Person> dragSource = applyDragSource(left);
  50. // Drop target Grid
  51. Grid<Person> right = createGridAndFillWithData(0);
  52. GridDropTarget<Person> dropTarget = applyDropTarget(right);
  53. // Layout the two grids
  54. Layout grids = new HorizontalLayout();
  55. grids.addComponents(left, right);
  56. grids.setWidth("100%");
  57. // Selection modes
  58. List<Grid.SelectionMode> selectionModes = Arrays
  59. .asList(Grid.SelectionMode.SINGLE, Grid.SelectionMode.MULTI);
  60. RadioButtonGroup<Grid.SelectionMode> selectionModeSelect = new RadioButtonGroup<>(
  61. "Selection mode", selectionModes);
  62. selectionModeSelect.setSelectedItem(Grid.SelectionMode.SINGLE);
  63. selectionModeSelect.addValueChangeListener(
  64. event -> left.setSelectionMode(event.getValue()));
  65. // Drop locations
  66. List<DropMode> dropLocations = Arrays.asList(DropMode.values());
  67. RadioButtonGroup<DropMode> dropLocationSelect = new RadioButtonGroup<>(
  68. "Allowed drop location", dropLocations);
  69. dropLocationSelect.setSelectedItem(DropMode.BETWEEN);
  70. dropLocationSelect.addValueChangeListener(
  71. event -> dropTarget.setDropMode(event.getValue()));
  72. Layout controls = new HorizontalLayout(selectionModeSelect,
  73. dropLocationSelect);
  74. addComponents(controls, grids);
  75. }
  76. private Grid<Person> createGridAndFillWithData(int numberOfItems) {
  77. Grid<Person> grid = new Grid<>();
  78. grid.setWidth("100%");
  79. grid.setItems(generateItems(numberOfItems));
  80. grid.addColumn(
  81. person -> person.getFirstName() + " " + person.getLastName())
  82. .setCaption("Name");
  83. grid.addColumn(person -> person.getAddress().getStreetAddress())
  84. .setCaption("Street Address");
  85. grid.addColumn(person -> person.getAddress().getCity())
  86. .setCaption("City");
  87. return grid;
  88. }
  89. private GridDragSource<Person> applyDragSource(Grid<Person> grid) {
  90. GridDragSource<Person> dragSource = new GridDragSource<>(grid);
  91. dragSource.setEffectAllowed(EffectAllowed.MOVE);
  92. // Set data generator
  93. dragSource.setDragDataGenerator("application/json", person -> {
  94. StringBuilder builder = new StringBuilder();
  95. builder.append("{");
  96. builder.append("\"First Name\":");
  97. builder.append("\"" + person.getFirstName() + "\"");
  98. builder.append(",");
  99. builder.append("\"Last Name\":");
  100. builder.append("\"" + person.getLastName() + "\"");
  101. builder.append("}");
  102. return builder.toString();
  103. });
  104. // Add drag start listener
  105. dragSource.addGridDragStartListener(event -> {
  106. draggedItems = event.getDraggedItems();
  107. log("START: " + draggedItems.size() + ", :"
  108. + draggedItems.stream().map(person -> person.getLastName())
  109. .collect(Collectors.joining(" ")));
  110. });
  111. // Add drag end listener
  112. dragSource.addGridDragEndListener(event -> {
  113. log("END: dropEffect=" + event.getDropEffect());
  114. if (event.getDropEffect() == DropEffect.MOVE
  115. && draggedItems != null) {
  116. // If drop is successful, remove dragged item from source Grid
  117. ((ListDataProvider<Person>) grid.getDataProvider()).getItems()
  118. .removeAll(draggedItems);
  119. grid.getDataProvider().refreshAll();
  120. // Remove reference to dragged items
  121. draggedItems = null;
  122. }
  123. });
  124. return dragSource;
  125. }
  126. private GridDropTarget<Person> applyDropTarget(Grid<Person> grid) {
  127. // Create and attach extension
  128. GridDropTarget<Person> dropTarget = new GridDropTarget<>(grid,
  129. DropMode.BETWEEN);
  130. dropTarget.setDropEffect(DropEffect.MOVE);
  131. // Add listener
  132. dropTarget.addGridDropListener(event -> {
  133. event.getDragSourceExtension().ifPresent(source -> {
  134. if (source instanceof GridDragSource) {
  135. ListDataProvider<Person> dataProvider = (ListDataProvider<Person>) event
  136. .getComponent().getDataProvider();
  137. List<Person> items = (List<Person>) dataProvider.getItems();
  138. // Calculate the target row's index
  139. int index = items.size();
  140. if (event.getDropTargetRow().isPresent()) {
  141. index = items.indexOf(event.getDropTargetRow().get())
  142. + (event.getDropLocation() == DropLocation.BELOW
  143. ? 1 : 0);
  144. }
  145. // Add dragged items to the target Grid
  146. items.addAll(index, draggedItems);
  147. dataProvider.refreshAll();
  148. log("DROP: dragData=" + event.getDataTransferText()
  149. + ", dragDataJson="
  150. + event.getDataTransferData("application/json")
  151. + ", target="
  152. + (event.getDropTargetRow().isPresent() ? event
  153. .getDropTargetRow().get().getFirstName()
  154. + " "
  155. + event.getDropTargetRow().get()
  156. .getLastName()
  157. : "[BODY]")
  158. + ", location=" + event.getDropLocation());
  159. }
  160. });
  161. });
  162. return dropTarget;
  163. }
  164. private List<Person> generateItems(int num) {
  165. return Stream.generate(() -> generateRandomPerson(new Random()))
  166. .limit(num).collect(Collectors.toList());
  167. }
  168. private Person generateRandomPerson(Random r) {
  169. return new Person(TestDataGenerator.getFirstName(r),
  170. TestDataGenerator.getLastName(r), "foo@bar.com",
  171. TestDataGenerator.getPhoneNumber(r),
  172. TestDataGenerator.getStreetAddress(r),
  173. TestDataGenerator.getPostalCode(r),
  174. TestDataGenerator.getCity(r));
  175. }
  176. }