Search code examples
gwtdrag-and-dropevent-handlingeventhandler

GWT native Drag&Drop Event-Handling (two sources, one target)


I'm trying to implement native drag & drop-feature in my project.

I have created two Image-Widgets image1 and image2:

image1.getElement().setDraggable(Element.DRAGGABLE_TRUE);
image2.getElement().setDraggable(Element.DRAGGABLE_TRUE);

Then i created the handlers for each one:

image1.addDragStartHandler(new DragStartHandler() {
        @Override
        public void onDragStart(DragStartEvent event) {
            event.setData("text", "images/img1.svg");
            });

image2.addDragStartHandler(new DragStartHandler() {
        @Override
        public void onDragStart(DragStartEvent event) {
            event.setData("text", "images/img2.svg");
            });

This is the DragOverHandler:

boundaryPanel.addDomHandler(new DragOverHandler() {
                    public void onDragOver(DragOverEvent event) {
                        boundaryPanel.getElement().getStyle().setBackgroundColor("#ffa");
                    }
                }, com.google.gwt.event.dom.client.DragOverEvent.getType());

Then i created the DropHandler, which should be able to decide which image was dragged. While Dragging, a new Panel should be created (for each dragged image another one) on the boundaryPanel. When i run the following code and drag image1 or image2, ap1 is shown for both of them. I think my if-else-conditions are not working correctly:

boundaryPanel.addDomHandler(new DropHandler() {             
      @Override
       public void onDrop(DropEvent event) {
         event.preventDefault();
         int x = (event.getNativeEvent().getClientX() - boundaryPanel.getAbsoluteLeft());
         int y = (event.getNativeEvent().getClientY() - boundaryPanel.getAbsoluteTop());
         boundaryPanel.getElement().getStyle().clearBackgroundColor();
         if(image1 != null){ <---think this is the problem
             //insert absolutePanel ap1
             ap1.add(ap2);
             ap1.add(ap3);
             ap1.add(ap4);          
             ap1.setWidgetPosition(ap3, 150, 0);
             ap1.setWidgetPosition(ap4, 474, 0);            
             boundaryPanel.add(ap1, x, y); 
          }
          else if (img2 != null) {
             //insert absolutePanel ap5
             ap5.add(ap6);
             ap5.add(ap7);
             ap5.add(ap8);          
             ap5.setWidgetPosition(ap7, 150, 0);
             ap5.setWidgetPosition(ap8, 474, 0);            
             boundaryPanel.add(ap5, x, y);                  
                    }
                }}, DropEvent.getType());   

What i'm doing wrong?

thanks for the help.


Solution

  • Code Snippet from your post:

      ........
      boundaryPanel.getElement().getStyle().clearBackgroundColor();
         if(image1 != null){ <---think this is the problem
             //insert absolutePanel ap1
      ......
    

    Reason:

    Yes the problem is with the if condition, image1 is an widget and you have already initialized and it will always have a value.

    More Info:

    When we are dragging image1 or image2, event is fired properly and in the onDrop we are checking the value of image1 widget is not null, and this condition is always true and hence you are getting ap1 printed all the times.

    Solution:

    Correct your if condition such that the conditional check is unique to image1 and image2 in the onDrop method.

    Approach 1:

    Add boolean variables isImage1Dragged and isImage2Dragged and have the default value as false. In the dragging part of Image1, set the variable isImage1Dragged to true and in the onDrop method modify the condition as follows

     if(isImage1Dragged) {
    
         // Do whatever you want when image1 is dragged
         ......
         ......
         isImage1Dragged = false;  
    
     } else if(isImage2Dragged) {
           // Do whatever you want when image2 is dragged
         ......
         ......
         isImage2Dragged = false;
     }