title: vaadin - how to swap components in a grid layout
body: <p>I have a split panel with an empty panel on the left side and right side is a grid layout. Users can drag elements from the left side and put them on the right side. The right side is a grid layout wth 4,3 matrix.</p>
  
  <ul>
  <li>We should be able to place components on the right side using drag and drop</li>
  <li>We should be able to swap the components already placed in the grid layout ( right side of the split panel).</li>
  </ul>
  
  <p>I am able to get the first point done. However, I have trouble with the second one.</p>
  
  <p>Also, I tried the Vaadin AddOn for Drag Drop but it does not work for me. SO I am using Vaadin 7.6.4 features of Drag and Drop.</p>
  
  <p>Can anyone help?</p>
  
  <pre><code>package com.example.dragdropvaadindemo;
  
  import javax.servlet.annotation.WebServlet;
  
  import java.util.logging.Logger;
  
  import com.vaadin.annotations.VaadinServletConfiguration;
  import com.vaadin.event.DataBoundTransferable;
  import com.vaadin.event.Transferable;
  import com.vaadin.event.dd.DragAndDropEvent;
  import com.vaadin.event.dd.DropHandler;
  import com.vaadin.event.dd.acceptcriteria.AcceptAll;
  import com.vaadin.event.dd.acceptcriteria.AcceptCriterion;
  import com.vaadin.server.Sizeable;
  import com.vaadin.server.VaadinRequest;
  import com.vaadin.server.VaadinServlet;
  import com.vaadin.ui.Button;
  import com.vaadin.ui.Button.ClickEvent;
  import com.vaadin.ui.Button.ClickListener;
  import com.vaadin.ui.Component;
  import com.vaadin.ui.DragAndDropWrapper;
  import com.vaadin.ui.DragAndDropWrapper.DragStartMode;
  import com.vaadin.ui.DragAndDropWrapper.WrapperTargetDetails;
  import com.vaadin.ui.DragAndDropWrapper.WrapperTransferable;
  import com.vaadin.ui.GridLayout;
  import com.vaadin.ui.HasComponents;
  import com.vaadin.ui.HorizontalSplitPanel;
  import com.vaadin.ui.UI;
  import com.vaadin.ui.VerticalLayout;
  import com.vaadin.annotations.Theme;
  
  @Theme("dragdropvaadindemo")
  public class DragdropvaadindemoUI extends UI {
  
      /**
       * 
       */
      private static final long   serialVersionUID = -586508616992840936L;
      final String                LEFT_WIDTH       = "20%";
      HorizontalSplitPanel        splitPanel;
      DragAndDropWrapper          wrapperA;
      DragAndDropWrapper          wrapperB;
  
      DragAndDropWrapper          splitPaneWrapper;
      Button                      buttonA;
      Button                      buttonB;
      private boolean             isDragMode       = false;
      private static final Logger logger           = Logger.getLogger(DragdropvaadindemoUI.class.getName());
  
      public int                  rowPosition;
  
      public int                  colPosition;
  
      public int getRowPosition() {
          return rowPosition;
      }
  
      public void setRowPosition(int rowPosition) {
          this.rowPosition = rowPosition;
      }
  
      public int getColPosition() {
          return colPosition;
      }
  
      public void setColPosition(int colPosition) {
          this.colPosition = colPosition;
      }
  
      @WebServlet(value = "/*", asyncSupported = true)
      @VaadinServletConfiguration(productionMode = false, ui = DragdropvaadindemoUI.class)
      public static class Servlet extends VaadinServlet {
  
          /**
           * 
           */
          private static final long serialVersionUID = -4605445550539288930L;
      }
  
      @Override
      protected void init(VaadinRequest request) {
  
          // LEFT SIDE
          EmptyPanel emptyPanel = new EmptyPanel("Left Panel");
          emptyPanel.setId("LeftPanel_0_0");
          emptyPanel.setSizeFull();
          final DragAndDropWrapper wrapperA = new DragAndDropWrapper(emptyPanel);
          wrapperA.setSizeFull();
          wrapperA.setId("Wrapper_LeftPanel_0_0");
          final VerticalLayout leftPanelLayout = new VerticalLayout();
          leftPanelLayout.addComponent(wrapperA);
          leftPanelLayout.setWidth("50%");
          // DragAndDropWrapper leftPanelLayoutWrapper = new DragAndDropWrapper(leftPanelLayout);
          // leftPanelLayoutWrapper.setDropHandler(new DropHandler() {
          //
          // private static final long serialVersionUID = -4676732504780260831L;
          //
          // @Override
          // public void drop(DragAndDropEvent event) {
          // leftPanelLayout.addComponent(event.getTransferable().getSourceComponent());
          //
          // }
          //
          // @Override
          // public AcceptCriterion getAcceptCriterion() {
          // return AcceptAll.get();
          // }
          //
          // });
          // leftPanelLayoutWrapper.setSizeFull();
  
          // RIGHT SIDE
          final GridLayout rightPanelLayout = new GridLayout(4, 3);
          rightPanelLayout.setStyleName("csstag");
  
          // add panels to the layout
          for (int i = 0; i &lt; 3; i++) {
              for (int j = 0; j &lt; 4; j++) {
                  setRowPosition(i);
                  setColPosition(j);
  
                  EmptyPanel emptyGridPanel = new EmptyPanel("RightPanel " + i + "," + j);
                  emptyGridPanel.setSizeFull();
                  emptyGridPanel.addStyleName("border-gridcell");
  
                  final DragAndDropWrapper rightPanelCellWrapper = new DragAndDropWrapper(emptyGridPanel);
                  rightPanelCellWrapper.setSizeFull();
  
                  final int col = getColPosition();
                  final int row = getRowPosition();
  
                  rightPanelCellWrapper.setId("Wrapper_EmptyPanel_" + row + "_" + col);
                  rightPanelCellWrapper.setDropHandler(new DropHandler() {
  
                      /**
                       * 
                       */
                      private static final long serialVersionUID = -5729628537182171336L;
  
                      @Override
                      public void drop(DragAndDropEvent event) {
  
                          // source details.
                          Transferable t = event.getTransferable();
                          Component from = t.getSourceComponent();
                          logger.info("wrapper component =" + from);
                          DragAndDropWrapper dragAndDropWrapper = (DragAndDropWrapper) from;
                          logger.info("dragged component count =" + dragAndDropWrapper.getComponentCount() + " with ID="
                                  + dragAndDropWrapper.getId());
                          String sourceWrapperId = dragAndDropWrapper.getId();
  
                          // target details.
                          WrapperTargetDetails details = (WrapperTargetDetails) event.getTargetDetails();
                          logger.info("target component =" + details.getTarget());
                          DragAndDropWrapper dragAndDropTargetWrapper = (DragAndDropWrapper) details.getTarget();
                          logger.info("target component count =" + dragAndDropTargetWrapper.getComponentCount() + " with ID="
                                  + dragAndDropTargetWrapper.getId());
                          String targetWrapperId = dragAndDropTargetWrapper.getId();
  
                          // if the source wrapper id is from outside
                          if ((sourceWrapperId.contains("LeftPanel_")) &amp;&amp; (targetWrapperId.contains("Wrapper_EmptyPanel_") ) ) {
                              // EmptyPanel draggedPanelWrapper = (EmptyPanel) event.getTransferable().getSourceComponent();
                              // logger.info("Empty Panel dragged is = " + draggedPanelWrapper.getPanelName() + " with ID="+
                              // draggedPanelWrapper.getId());
                              // logger.info("Empty Panel dragged is = " + draggedPanel.getPanelName() + " with ID=" +
                              // draggedPanel.getId());
                              logger.info("Removing existing component from the location=" + row + "," + col);
                              rightPanelLayout.removeComponent(col, row);
                              logger.info("Adding new component from the location=" + row + "," + col);
                              dragAndDropWrapper.setDragStartMode(DragStartMode.WRAPPER);
                              rightPanelLayout.addComponent(dragAndDropWrapper, col, row);
  
                              // once an empty panel is added, then create a new one in the left side panel.
                              EmptyPanel emptyPanel = new EmptyPanel("Left Panel");
                              emptyPanel.setId("GridPanel_" + row + "_" + col);
                              emptyPanel.setSizeFull();
                              DragAndDropWrapper emptyPanelWrapper = new DragAndDropWrapper(emptyPanel);
                              emptyPanelWrapper.setId("Wrapper_LeftPanel_" + row + "_" + col);
                              leftPanelLayout.addComponent(emptyPanelWrapper);
                              emptyPanelWrapper.setDragStartMode(DragStartMode.WRAPPER);
                              emptyPanelWrapper.setSizeFull();
                              // GridPanel_
                          } else if (sourceWrapperId.contains("GridPanel_")  &amp;&amp; (targetWrapperId.contains("GridPanel_") ) ) {
                             String sourceRowColStr = sourceWrapperId.replace("GridPanel_", "");
                             String sourceIndexArr[] = sourceRowColStr.split("_");
                             logger.info("sourceWrapperId="+sourceWrapperId + "#sourceRowColStr="+sourceRowColStr + "# row pos="+sourceIndexArr[0] + "# col pos = "+sourceIndexArr[1]);
                          } else {
                              // error criteria.cannot add component.
                          }
                      }
  
                      @Override
                      public AcceptCriterion getAcceptCriterion() {
                          return AcceptAll.get();
                      }
                  });
  
                  rightPanelLayout.addComponent(rightPanelCellWrapper, j, i);
  
                  logger.info("Added panel at location=" + i + "," + j);
              }
          }
  
          rightPanelLayout.setSizeFull();
  
          // OVERALL PANEL
          final HorizontalSplitPanel splitPanel = new HorizontalSplitPanel();
          // splitPanel.setFirstComponent(leftPanelLayoutWrapper);
          splitPanel.setFirstComponent(leftPanelLayout);
          splitPanel.setSecondComponent(rightPanelLayout);
          splitPanel.setSizeFull();
          splitPanel.setSplitPosition(10, Sizeable.Unit.PERCENTAGE);
          splitPanel.setLocked(true);
  
          final Button dragMode = new Button("Drag Mode On");
          dragMode.addClickListener(new ClickListener() {
  
              private static final long serialVersionUID = -926098671937004974L;
  
              @Override
              public void buttonClick(ClickEvent event) {
                  isDragMode = !isDragMode;
                  if (isDragMode) {
                      dragMode.setCaption("Drag Mode Off");
                      wrapperA.setDragStartMode(DragStartMode.WRAPPER);
                      // wrapperB.setDragStartMode(DragStartMode.WRAPPER);
  
                  } else {
                      dragMode.setCaption("Drag Mode On");
                      wrapperA.setDragStartMode(DragStartMode.NONE);
                      // wrapperB.setDragStartMode(DragStartMode.NONE);
                  }
  
              }
  
          });
  
          // outer layout.
          VerticalLayout layout = new VerticalLayout();
          layout.addComponent(dragMode);
          layout.addComponent(splitPanel);
          layout.setSizeFull();
  
          this.setContent(layout);
          this.setSizeFull();
      }
  
      Component findComponentWithId(HasComponents root, String id) {
          for (Component child : root) {
              if (id.equals(child.getId())) {
                  // found it!
                  return child;
              } else if (child instanceof HasComponents) {
                  // recursively go through all children that themselves have children
                  return findComponentWithId((HasComponents) child, id);
              }
          }
          // none was found
          return null;
      }
  
      // find components by type.
      Component findComponentWithNamePattern(HasComponents root, String namePattern) {
          for (Component child : root) {
              if ((child.getId()).contains(namePattern)) {
                  // found it!
                  return child;
              } else if (child instanceof HasComponents) {
                  // recursively go through all children that themselves have children
                  return findComponentWithId((HasComponents) child, namePattern);
              }
          }
          // none was found
          return null;
      }
  }
  </code></pre>
  
  <p>Here is the Empoty Panel that supports it.</p>
  
  <pre><code>package com.example.dragdropvaadindemo;
  
  import com.vaadin.ui.Label;
  import com.vaadin.ui.Panel;
  import com.vaadin.ui.VerticalLayout;
  
  public class EmptyPanel extends Panel{
  
      private String panelName;
  
      public String getPanelName() {
          return panelName;
      }
  
      public void setPanelName(String panelName) {
          this.panelName = panelName;
      }
  
      public EmptyPanel(String panelName){
          this.panelName = panelName;
          VerticalLayout vLayout = new VerticalLayout();
          setContent(vLayout);
          vLayout.setMargin(true);
          vLayout.setSizeFull();
          Label lblA = new Label(panelName);
          lblA.setWidth("30%");
          //lblA.setDescription(panelName);
          this.setDescription(panelName);
  
          vLayout.addComponent(lblA);
      }
  }
  </code></pre>