aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java4
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java24
-rw-r--r--client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java45
-rw-r--r--uitest/src/main/java/com/vaadin/tests/dnd/DragSourcesInTabSheet.java83
4 files changed, 124 insertions, 32 deletions
diff --git a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
index 7f8fb429a2..f1ac15703e 100644
--- a/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
+++ b/client/src/main/java/com/vaadin/client/connectors/grid/GridDragSourceConnector.java
@@ -352,8 +352,6 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
@Override
public void onUnregister() {
- super.onUnregister();
-
// Remove draggable from all row elements in the escalator
Range visibleRange = getEscalator().getVisibleRowRange();
for (int i = visibleRange.getStart(); i < visibleRange.getEnd(); i++) {
@@ -371,6 +369,8 @@ public class GridDragSourceConnector extends DragSourceExtensionConnector {
.setDelayToCancelTouchScroll(-1);
touchScrollDelayUsed = false;
}
+
+ super.onUnregister();
}
private Grid<JsonObject> getGrid() {
diff --git a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
index 61ff4dea8a..a0f6280ca5 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DragSourceExtensionConnector.java
@@ -27,7 +27,6 @@ import com.google.gwt.dom.client.Style.Position;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
-import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.annotations.OnStateChange;
import com.vaadin.client.ui.AbstractComponentConnector;
@@ -62,15 +61,11 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
private final EventListener dragStartListener = this::onDragStart;
private final EventListener dragEndListener = this::onDragEnd;
- /**
- * Widget of the drag source component.
- */
private Widget dragSourceWidget;
@Override
protected void extend(ServerConnector target) {
- dragSourceWidget = ((ComponentConnector) target).getWidget();
-
+ dragSourceWidget = ((AbstractComponentConnector) target).getWidget();
// HTML5 DnD is by default not enabled for mobile devices
if (BrowserInfo.get().isTouchDevice() && !getConnection()
.getUIConnector().isMobileHTML5DndEnabled()) {
@@ -138,14 +133,21 @@ public class DragSourceExtensionConnector extends AbstractExtensionConnector {
@Override
public void onUnregister() {
- super.onUnregister();
+ AbstractComponentConnector parent = (AbstractComponentConnector) getParent();
+ // if parent is null, the whole component has been removed,
+ // no need to do clean up then
+ if (parent != null) {
+ parent.onDragSourceDetached();
- Element dragSource = getDraggableElement();
+ Element dragSource = getDraggableElement();
- removeDraggable(dragSource);
- removeDragListeners(dragSource);
+ removeDraggable(dragSource);
+ removeDragListeners(dragSource);
- ((AbstractComponentConnector) getParent()).onDragSourceDetached();
+ dragSourceWidget = null;
+ }
+
+ super.onUnregister();
}
@OnStateChange("resources")
diff --git a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
index 060a12f658..cd23b3bc74 100644
--- a/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
+++ b/client/src/main/java/com/vaadin/client/extensions/DropTargetExtensionConnector.java
@@ -26,7 +26,6 @@ import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
-import com.vaadin.client.ComponentConnector;
import com.vaadin.client.ServerConnector;
import com.vaadin.client.ui.AbstractComponentConnector;
import com.vaadin.shared.ui.Connect;
@@ -76,9 +75,6 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
private final EventListener dragLeaveListener = this::onDragLeave;
private final EventListener dropListener = this::onDrop;
- /**
- * Widget of the drop target component.
- */
private Widget dropTargetWidget;
/**
@@ -89,7 +85,7 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
@Override
protected void extend(ServerConnector target) {
- dropTargetWidget = ((ComponentConnector) target).getWidget();
+ dropTargetWidget = ((AbstractComponentConnector) target).getWidget();
// HTML5 DnD is by default not enabled for mobile devices
if (BrowserInfo.get().isTouchDevice() && !getConnection()
@@ -139,13 +135,21 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
@Override
public void onUnregister() {
- super.onUnregister();
+ AbstractComponentConnector parent = (AbstractComponentConnector) getParent();
+ // parent is null when the component has been removed,
+ // clean up only if only the extension was removed
+ if (parent != null) {
+ parent.onDropTargetDetached();
- removeDropListeners(getDropTargetElement());
- ((AbstractComponentConnector) getParent()).onDropTargetDetached();
+ removeDropListeners(getDropTargetElement());
- // Remove drop target indicator
- removeDropTargetStyle();
+ // Remove drop target indicator
+ removeDropTargetStyle();
+
+ dropTargetWidget = null;
+ }
+
+ super.onUnregister();
}
/**
@@ -313,12 +317,13 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* Initiates a server RPC for the drop event.
*
* @param types
- * List of data types from {@code DataTransfer.types} object.
+ * List of data types from {@code DataTransfer.types} object.
* @param data
- * Map containing all types and corresponding data from the {@code
+ * Map containing all types and corresponding data from the
+ * {@code
* DataTransfer} object.
* @param dropEffect
- * The desired drop effect.
+ * The desired drop effect.
*/
protected void sendDropEventToServer(List<String> types,
Map<String, String> data, String dropEffect,
@@ -329,15 +334,17 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
/**
* Add class name for the drop target element indicating that data can be
* dropped onto it. The class name has the following format:
+ *
* <pre>
* [primaryStyleName]-droptarget
* </pre>
- * The added class name is update
- * automatically by the framework when the primary style name changes.
+ *
+ * The added class name is update automatically by the framework when the
+ * primary style name changes.
*/
protected void addDropTargetStyle() {
- getDropTargetElement().addClassName(
- getStylePrimaryName(getDropTargetElement())
+ getDropTargetElement()
+ .addClassName(getStylePrimaryName(getDropTargetElement())
+ STYLE_SUFFIX_DROPTARGET);
}
@@ -346,8 +353,8 @@ public class DropTargetExtensionConnector extends AbstractExtensionConnector {
* be dropped onto it.
*/
protected void removeDropTargetStyle() {
- getDropTargetElement().removeClassName(
- getStylePrimaryName(getDropTargetElement())
+ getDropTargetElement()
+ .removeClassName(getStylePrimaryName(getDropTargetElement())
+ STYLE_SUFFIX_DROPTARGET);
}
diff --git a/uitest/src/main/java/com/vaadin/tests/dnd/DragSourcesInTabSheet.java b/uitest/src/main/java/com/vaadin/tests/dnd/DragSourcesInTabSheet.java
new file mode 100644
index 0000000000..a493f987a3
--- /dev/null
+++ b/uitest/src/main/java/com/vaadin/tests/dnd/DragSourcesInTabSheet.java
@@ -0,0 +1,83 @@
+package com.vaadin.tests.dnd;
+
+import com.vaadin.annotations.Widgetset;
+import com.vaadin.server.VaadinRequest;
+import com.vaadin.shared.ui.grid.DropMode;
+import com.vaadin.tests.components.AbstractTestUIWithLog;
+import com.vaadin.tests.data.bean.Person;
+import com.vaadin.ui.Button;
+import com.vaadin.ui.Grid;
+import com.vaadin.ui.Label;
+import com.vaadin.ui.TabSheet;
+import com.vaadin.ui.VerticalLayout;
+import com.vaadin.ui.Window;
+import com.vaadin.ui.components.grid.GridDragSource;
+import com.vaadin.ui.components.grid.GridDropTarget;
+import com.vaadin.ui.dnd.DragSourceExtension;
+import com.vaadin.ui.dnd.DropTargetExtension;
+
+@Widgetset("com.vaadin.DefaultWidgetSet")
+public class DragSourcesInTabSheet extends AbstractTestUIWithLog {
+
+ @Override
+ protected void setup(VaadinRequest request) {
+ TabSheet tabSheet = new TabSheet();
+ addComponent(tabSheet);
+
+ tabSheet.addTab(new VerticalLayout(createLabels()))
+ .setCaption("Labels");
+
+ Button dsButton = new Button("DragSource");
+ new DragSourceExtension<>(dsButton)
+ .addDragEndListener(event -> log("drag end button"));
+ Button dtButton = new Button("DropTarget");
+ new DropTargetExtension<>(dtButton).addDropListener(event -> log("drop "
+ + event.getDragSourceComponent().orElse(null) + " on button"));
+ tabSheet.addTab(new VerticalLayout(dsButton, dtButton))
+ .setCaption("Buttons");
+
+ tabSheet.addTab(new VerticalLayout(createGrids())).setCaption("Grids");
+
+ addComponent(new Button("Open window", event -> openWindow()));
+ }
+
+ private Label[] createLabels() {
+ Label dragSource = new Label("DragSource");
+ new DragSourceExtension<>(dragSource)
+ .addDragEndListener(event -> log("drag end label"));
+ Label dropTarget = new Label("DropTarget");
+ new DropTargetExtension<>(dropTarget).addDropListener(event -> log(
+ "drop " + event.getDragSourceComponent().orElse(null)
+ + " on label"));
+ return new Label[] { dragSource, dropTarget };
+ }
+
+ private Grid[] createGrids() {
+ Grid<Person> dsGrid = new Grid<>(Person.class);
+ dsGrid.setItems(Person.createTestPerson1(), Person.createTestPerson2());
+ new GridDragSource<>(dsGrid).addGridDragEndListener(event -> log(
+ "drag end " + event.getDraggedItems().iterator().next()));
+ Grid<Person> dtGrid = new Grid<>(Person.class);
+ dtGrid.setItems(Person.createTestPerson1(), Person.createTestPerson2());
+ new GridDropTarget<>(dtGrid, DropMode.BETWEEN)
+ .addGridDropListener(event -> log("drop on grid row "
+ + event.getDropTargetRow().orElse(null) + " "
+ + event.getDragData().orElse(null)));
+ return new Grid[] { dsGrid, dtGrid };
+ }
+
+ private void openWindow() {
+ Window window = new Window("Window with drag sources");
+ VerticalLayout layout = new VerticalLayout();
+ layout.addComponents(createLabels());
+ layout.addComponents(createGrids());
+ window.setContent(layout);
+ addWindow(window);
+ }
+
+ @Override
+ protected String getTestDescription() {
+ return "Verify that removing drag source and drop target components in a tabsheet/window works";
+ }
+
+}