2016-10-16 5 views
0

Ich habe 3 Tabellen in Vaadin:Drag and Drop zwischen Tabellen in Horizontallayout funktioniert nicht

3 Tables within a horizontal Layout

Mein Problem ist nun, dass Drag & Tropfen nicht funktioniert. Mein Code ist der folgende:

@Theme("valo") 
@SpringView(name = TaskboardView.VIEW_NAME) 
public class TaskboardView extends VerticalLayout implements View { 

private enum TableType { 
    DONE, PROGRESS, OPEN; 
} 

private static final long serialVersionUID = 1L; 
private final Logger logger = LoggerFactory.getLogger(TaskboardView.class); 
public static final String VIEW_NAME = "taskboard"; 

// Components: 
private SprintController sprintController = new SprintController(); 
private TaskController taskController = new TaskController(); 
private Sprint sprint; 
private Set<Task> allTasks; 
private List<Task> openTasks = new ArrayList<Task>(); 
private List<Task> inProgressTasks = new ArrayList<Task>(); 
private List<Task> doneTasks = new ArrayList<Task>(); 

// UI Components: 
private Table openTable = new Table("Open Tasks:"); 
private int openTableId = 1; 
private Table inProgressTable = new Table("Tasks in Progress"); 
private int inProgressTableId = 1; 
private Table doneTable = new Table("Done Tasks"); 
private int doneTableId = 1; 
private TextField sprintName = new TextField(); 
private OpenTableDropHandler openTableDropHandler = new OpenTableDropHandler(); 
private InProgressTableDropHandler inProgressTableDropHandler = new InProgressTableDropHandler(); 
DoneTableHandler doneTableHandler = new DoneTableHandler(); 

@PostConstruct 
void init() { 
    logger.info("Initializing Taskboard View..."); 
    try { 
     this.sprint = sprintController.getActiveSprint(); 
     this.allTasks = sprintController.getTasksInSprint(this.sprint.getId().intValue()); 
     sortSprintTasks(this.allTasks); 
     this.sprintName.setNullRepresentation("-- No active Sprint found --"); 
     this.sprintName.setValue(this.sprint.getSprintName()); 
     this.sprintName.setWidth("800px"); 
     this.sprintName.setReadOnly(true); 
     this.sprintName.addStyleName("align-center"); // sets Allignment of 
                 // the textfield!!! 

    } catch (NoActiveSprintReceivedException | NoSprintsExistException | IOException e) { 
     logger.error("Something went wrong initializing active Sprint. The taskboard can't be displayed.", e); 
     Notification.show("No Active Sprint found!", Notification.Type.ERROR_MESSAGE); 
     e.printStackTrace(); 
     return; 
    } catch (TaskCanNotBeAllocatedException e) { 
     logger.error("Task of sprint couldn't be allocated to an status.", e); 
     Notification.show("Error! \n \n Task of sprint couldn't be allocated to an status.", 
       Notification.Type.ERROR_MESSAGE); 
     e.printStackTrace(); 
     return; 
    } 
    // Layout for Sprint Name: 
    VerticalLayout headLayout = new VerticalLayout(); 
    headLayout.setSpacing(true); 
    headLayout.setSizeFull(); 
    ; 
    headLayout.setMargin(true); 
    headLayout.addComponent(this.sprintName); 
    headLayout.setComponentAlignment(this.sprintName, Alignment.MIDDLE_CENTER); 

    setSizeFull(); 
    setSpacing(true); 
    setMargin(true); 
    // Layout: 
    VerticalLayout verticalLayout = new VerticalLayout(); 
    verticalLayout.setSpacing(true); 

    // Layout for Board: 
    HorizontalLayout taskBoardLayout = new HorizontalLayout(); 
    taskBoardLayout.setSizeUndefined(); 
    taskBoardLayout.setSpacing(true); 
    taskBoardLayout.setMargin(true); 

    // Adding to HorizontalLayout(TaskBoadLayout) 
    try { 
     initTable(this.openTable, TableType.OPEN); 
     initTable(this.inProgressTable, TableType.PROGRESS); 
     initTable(this.doneTable, TableType.DONE); 
    } catch (IOException e) { 
     logger.error("Something went wrong initizalizing Tables."); 
     Notification.show("Error! \n \n Couldn't initialize tables.", Notification.Type.ERROR_MESSAGE); 
     return; 
    } 

    taskBoardLayout.addComponent(openTable); 
    taskBoardLayout.addComponent(inProgressTable); 
    taskBoardLayout.addComponent(doneTable); 

    // Adding to VerticalLayout (MainLayout) 
    verticalLayout.addComponent(headLayout); 
    verticalLayout.addComponent(taskBoardLayout); 
    verticalLayout.setComponentAlignment(taskBoardLayout, Alignment.MIDDLE_CENTER); 
    addComponent(verticalLayout); 
} 

/** 
* Sorts the tasks of the sprint to the required lists like open, in 
* Progress, done. 
* 
* @param tasks 
* @throws TaskCanNotBeAllocatedException 
*/ 
private void sortSprintTasks(Set<Task> tasks) throws TaskCanNotBeAllocatedException { 
    logger.info("sortSprintTask(Set<Task>tasks): Sorting Tasks to the required lists..."); 
    for (Task t : tasks) { 
     logger.info("Checking Sprint Status of Task >>>> " + t.getHeadLine() + " <<<<"); 
     logger.info("Status: " + t.getStatus()); 
     if (t.getStatus().equals(WorkflowStatusConfigurator.open)) { 
      this.openTasks.add(t); 
     } else if (t.getStatus().equals(WorkflowStatusConfigurator.inProgress)) { 
      this.inProgressTasks.add(t); 
     } else if (t.getStatus().equals(WorkflowStatusConfigurator.done)) { 
      this.doneTasks.add(t); 
     } else { 
      throw new TaskCanNotBeAllocatedException(
        "Task can't be allocated to a sprint status: " + WorkflowStatusConfigurator.open + ", " 
          + WorkflowStatusConfigurator.inProgress + ", " + WorkflowStatusConfigurator.done + "."); 
     } 

    } 
} 

@Override 
public void enter(ViewChangeEvent event) { 
    // TODO Auto-generated method stub 

} 

/** 
* Creates the tables depending on the type parameter 
* 
* @param table 
* @param type 
* @throws IOException 
* @throws ClientProtocolException 
*/ 
private void initTable(Table table, TableType type) throws ClientProtocolException, IOException { 
    table.setSelectable(true); 
    table.setImmediate(true); 
    table.setDragMode(TableDragMode.ROW); 
    table.addContainerProperty("ID", Long.class, null); 
    table.setColumnWidth("ID", 50); 
    table.addContainerProperty("Headline", String.class, null); 
    table.setColumnWidth("Headline", 300); 
    table.addContainerProperty("Task-Type", String.class, null); 
    table.setColumnWidth("Task-Type", 120); 
    table.addContainerProperty("Assignee", String.class, null); 
    table.setColumnWidth("Assignee", 100); 

    if (type.equals(TableType.OPEN) && this.openTasks.size() > 0) { 
     logger.info("Loading values of Open Tasks Table..."); 
     table.setDropHandler(this.openTableDropHandler); 
     for (Task t : this.openTasks) { 
      String assignee = this.taskController.getAssigneeInTask(t.getId().intValue()).getUserName(); 
      table.addItem(new Object[] { t.getId(), t.getHeadLine(), t.getTaskType(), assignee }, this.openTableId); 
      this.openTableId++; 
     } 
     return; 

    } 

    if (type.equals(TableType.PROGRESS) && this.inProgressTasks.size() > 0) { 
     logger.info("Loading values of Progress Tasks Table..."); 
     table.setDropHandler(this.inProgressTableDropHandler); 
     for (Task t : this.inProgressTasks) { 
      String assignee = this.taskController.getAssigneeInTask(t.getId().intValue()).getUserName(); 
      table.addItem(new Object[] { t.getId(), t.getHeadLine(), t.getTaskType(), assignee }, this.inProgressTableId); 
      this.inProgressTableId++; 
     } 
     return; 
    } 

    if (type.equals(TableType.DONE) && this.doneTasks.size() > 0) { 
     logger.info("Loading values of Done Tasks Table..."); 
     table.setDropHandler(this.doneTableHandler); 
     for (Task t : this.doneTasks) { 
      String assignee = this.taskController.getAssigneeInTask(t.getId().intValue()).getUserName(); 
      table.addItem(new Object[] { t.getId(), t.getHeadLine(), t.getTaskType(), assignee }, this.doneTableId); 
      this.doneTableId++; 
     } 
     return; 
    } 
} 

private int giveEncreasedAvailableTableId(TableType tableType) { 
    if(tableType.equals(TableType.OPEN)){ 
     this.openTableId++; 
     return this.openTableId; 
    }else if(tableType.equals(TableType.PROGRESS)){ 
     this.inProgressTableId++; 
     return this.inProgressTableId; 
    }else if(tableType.equals(TableType.DONE)){ 
     this.doneTableId++; 
     return this.doneTableId; 
    }else{ 
     return -1; 
    } 

} 

private class OpenTableDropHandler implements DropHandler{ 

    private static final long serialVersionUID = 1L; 
    private final Logger logger = LoggerFactory.getLogger(OpenTableDropHandler.class); 

    @Override 
    public void drop(DragAndDropEvent event) { 
     // Wrapper for the object that is dragged 
     logger.info("Received Drag and Drop Event from OpenTable..."); 
     DataBoundTransferable t = (DataBoundTransferable) event.getTransferable(); 
     AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event.getTargetDetails()); 
     Object itemId = t.getItemId(); 
     Long id = (Long) t.getSourceContainer().getItem(itemId).getItemProperty("ID").getValue(); 
     try { 
      Task taskToAdd = taskController.getById(id.intValue()); 
      String author = taskController.getAuthorInTask(taskToAdd.getId().intValue()).getUserName(); 
      if (t.getSourceComponent() != openTable && dropData.getTarget().equals(inProgressTable)) { 
       logger.info("Preparing Task Update to InProgress..."); 
       openTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), 
         taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.OPEN)); 
       openTasks.add(taskToAdd); 
       inProgressTable.removeItem(itemId); 
       inProgressTasks.remove(taskToAdd); 
      }else if(t.getSourceComponent() != openTable && dropData.getTarget().equals(doneTable)){ 
       logger.info("Preparing Task Update to Done..."); 
       openTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), 
         taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.OPEN)); 
       openTasks.add(taskToAdd); 
       doneTable.removeItem(itemId); 
       doneTasks.remove(taskToAdd); 
      }else{ 
       logger.info("Do nothing..."); 
       return; 
      } 
      taskToAdd.setStatus(WorkflowStatusConfigurator.open); 
      logger.info("Sending updates of taskboard to webservice..."); 
      HttpResponse response = taskController.put(taskToAdd, taskToAdd.getId().intValue()); 
      MainView.navigator.navigateTo(TaskboardView.VIEW_NAME); 
    //    HttpResponse authorResponse =  taskController.setAuthorInTask(taskToAdd.getAuthor().getId().intValue(), 
//      taskToAdd.getId().intValue()); 
    //    HttpResponse assigneeResponse = taskController.setAssigneeInTask(taskToAdd.getAssignee().getId().intValue(), 
//      taskToAdd.getId().intValue()); 

     } catch (ClientProtocolException e) { 

      logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); 
     } catch (IOException e) { 
      logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); 
     } 

    } 

    @Override 
    public AcceptCriterion getAcceptCriterion() { 
     return AcceptAll.get(); 
    } 

} 

private class InProgressTableDropHandler implements DropHandler{ 


    private static final long serialVersionUID = 1L; 
    private final Logger logger = LoggerFactory.getLogger(InProgressTableDropHandler.class); 

    @Override 
    public void drop(DragAndDropEvent event) { 
     // Wrapper for the object that is dragged 
     logger.info("Received Drag and Drop Event from In Progress Table."); 
     DataBoundTransferable t = (DataBoundTransferable) event.getTransferable(); 
     AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event.getTargetDetails()); 
     Object itemId = t.getItemId(); 
     Long id = (Long) t.getSourceContainer().getItem(itemId).getItemProperty("ID").getValue(); 


     try { 
      Task taskToAdd = taskController.getById(id.intValue()); 
      String author = taskController.getAuthorInTask(taskToAdd.getId().intValue()).getUserName(); 
      if (t.getSourceComponent() != inProgressTable && dropData.getTarget().equals(doneTable)){ 
       inProgressTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), 
         taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.PROGRESS)); 
       doneTable.removeItem(itemId); 
       inProgressTasks.add(taskToAdd); 
       doneTasks.remove(taskToAdd); 
      }else if(t.getSourceComponent() != inProgressTable && dropData.getTarget().equals(openTable)){ 
       inProgressTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), 
         taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.PROGRESS)); 
       openTable.removeItem(itemId); 
       inProgressTasks.add(taskToAdd); 
       openTasks.remove(taskToAdd); 
      }else{ 
       return; 
      } 
      logger.info("Sending updates of taskboard to webservice..."); 
      taskToAdd.setStatus(WorkflowStatusConfigurator.inProgress); 
       HttpResponse response = taskController.put(taskToAdd, taskToAdd.getId().intValue()); 
      MainView.navigator.navigateTo(TaskboardView.VIEW_NAME); 
     }catch (ClientProtocolException e) { 
      logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); 
     } catch (IOException e) { 
      logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); 
     } 

    } 

    @Override 
    public AcceptCriterion getAcceptCriterion() { 
     return AcceptAll.get(); 
    } 

} 

private class DoneTableHandler implements DropHandler{ 


    private static final long serialVersionUID = 1L; 
    private final Logger logger = LoggerFactory.getLogger(DoneTableHandler.class); 

    @Override 
    public void drop(DragAndDropEvent event) { 
     logger.info("Received Drag and Drop Event from In Done Table."); 
     DataBoundTransferable t = (DataBoundTransferable) event.getTransferable(); 
     AbstractSelectTargetDetails dropData = ((AbstractSelectTargetDetails) event.getTargetDetails()); 
     Object itemId = t.getItemId(); 
     Long id = (Long) t.getSourceContainer().getItem(itemId).getItemProperty("ID").getValue(); 
     try { 
      Task taskToAdd = taskController.getById(id.intValue()); 
      String author = taskController.getAuthorInTask(taskToAdd.getId().intValue()).getUserName(); 
      if (t.getSourceComponent() != doneTable && dropData.getTarget().equals(inProgressTable)){ 
       doneTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), 
         taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.DONE)); 
       inProgressTable.removeItem(itemId); 
       doneTasks.add(taskToAdd); 
       inProgressTasks.remove(taskToAdd); 
      }else if(t.getSourceComponent() != doneTable && dropData.getTarget().equals(openTable)){ 
       doneTable.addItem(new Object[] { taskToAdd.getId(), taskToAdd.getHeadLine(), 
         taskToAdd.getTaskType(), author, taskToAdd.getStatus() }, giveEncreasedAvailableTableId(TableType.DONE)); 
       openTable.removeItem(itemId); 
       doneTasks.add(taskToAdd); 
       openTasks.remove(taskToAdd); 
      }else{ 
       return; 
      } 
      logger.info("Sending updates of taskboard to webservice..."); 
      taskToAdd.setStatus(WorkflowStatusConfigurator.done); 
      HttpResponse response = taskController.put(taskToAdd, taskToAdd.getId().intValue()); 
      MainView.navigator.navigateTo(TaskboardView.VIEW_NAME); 
     }catch (ClientProtocolException e) { 
      logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); 
     } catch (IOException e) { 
      logger.warn("Something went wrong during Drag and Drop Process", e.getCause()); 
     } 

    } 

    @Override 
    public AcceptCriterion getAcceptCriterion() { 
     return AcceptAll.get(); 
    } 

} 

} 

Hat jemand eine Idee oder zumindest eine Ahnung, warum das nicht funktioniert? Ich schrieb einen Code, der dem gleichen Muster folgte, und es funktionierte gut. Der einzige Unterschied ist, dass ich dort kein horizontales Layout verwende. Und jetzt reagieren die In Progress und Done Tabelle nicht darauf, eine Reihe auf sie zu ziehen.

+0

ich habe gerade versucht, ein einfaches Beispiel ähnlich wie bei Ihnen und es funktioniert gut mit Vaadin 7.7.3. Mein Vorzug ist, dass Sie die abgelegten Daten in Ihren Handlern in den "else {return};" - Zweigen herausfiltern. Wenn ich 'DoneTableHandler' betrachte, sehe ich 'if (t.getSourceComponent()! = DoneTable && dropData.getTarget(). Equals (inProgressTable)) {' was meiner Meinung nach nicht ganz korrekt ist. Der Handler für die Ablage sollte mit Daten umgehen, die für diese Komponente abgelegt wurden. Daher sollte die Quelle entweder die Tabelle _open_ oder _in progress_ sein und die Zieldatei _done_. – Morfic

Antwort

0

Off-Thema: Warum haben Sie @Theme("valo") auf Ihrer Sicht? Soweit ich das mit der UI Klasse verwendet werden wissen ...


On-Thema:

Wie ich in meinem Kommentar sagte glaube ich nicht, es zu HorizontalLayout in engen Zusammenhang steht. Entweder haben Sie die Drag Source und Drop Ziel Konzepte falsch verstanden oder es rutschte einfach in den Code.

Wie es auch in der the docs Ziehen beginnt, sich von einer Quelle beschrieben ist, und das Ereignis der dropping die Daten auf dem Ziel durch einen DropHandler gehandhabt wird. Wenn Sie einen Blick auf Ihre Quellen nehmen, DoneTableHandler zum Beispiel, können Sie

if (t.getSourceComponent() != doneTable && dropData.getTarget().equals(inProgressTable)){ 
    ... 
}else if(t.getSourceComponent() != doneTable && dropData.getTarget().equals(openTable)){ 
    ... 
}else{ 
    return; 
} 

sehen Da Sie für Tropfen auf Ihrem doneTable hören wird es das Ziel und Quellen kann nur die openTable oder inProgressTable, nicht umgekehrt. Ich habe eine Ahnung, dass, wenn Sie eine Log-Zeile im else Zweig hinzufügen werden Sie es bei jedem Drag & Drop sehen.


Im folgenden finden Sie eine Arbeitsprobe in Vaadin 7.7.3 mit HorizontalLayout und 3 Tabellen, ähnlich wie bei Ihnen zu sehen. Es ist schnell und schmutzig, so gibt es Raum für Verbesserungen (Vorschläge sind willkommen), aber (zB: position of dropped items), unterstützt es multirow ziehen und auch die AcceptCriterion Filter fällt aus der Quelltabelle oder eine andere Komponente als den erwarteten:

public class DragAndDropTables extends HorizontalLayout { 

    public DragAndDropTables() { 
     // leave some space between the tables 
     setSpacing(true); 

     // tables 
     Table toDoTable = createTable("To do"); 
     Table inProgressTable = createTable("In progress"); 
     Table doneTable = createTable("Done"); 

     // drop handlers which allow only drops from expected sources 
     configureDragAndDrop(toDoTable, inProgressTable, doneTable); 
     configureDragAndDrop(inProgressTable, toDoTable, doneTable); 
     configureDragAndDrop(doneTable, toDoTable, inProgressTable); 

     // some table to make sure AcceptCriterion allows drops only from expected sources 
     Table tableNotAcceptableForDrops = createTable("Drops from here will not be accepted"); 
     configureDragAndDrop(tableNotAcceptableForDrops); 
     tableNotAcceptableForDrops.addItem(new Task(100, "Not droppable task")); 

     // add some dummy data 
     for (int i = 0; i < 10; i++) { 
      toDoTable.addItem(new Task(i, "Task " + i)); 
     } 

     // add the tables to the UI 
     addComponent(toDoTable); 
     addComponent(inProgressTable); 
     addComponent(doneTable); 
     addComponent(tableNotAcceptableForDrops); 
    } 

    private Table createTable(String caption) { 
     // basic table setup 
     Table table = new Table(caption); 
     BeanItemContainer<Task> itemContainer = new BeanItemContainer<>(Task.class); 
     table.setContainerDataSource(itemContainer); 
     table.setMultiSelect(true); 
     table.setSelectable(true); 
     table.setPageLength(10); 
     return table; 
    } 

    private void configureDragAndDrop(Table table, Table... acceptedSources) { 
     // drag & drop configuration 
     table.setDragMode(Table.TableDragMode.MULTIROW); 
     table.setDropHandler(new DropHandler() { 
      @Override 
      public void drop(DragAndDropEvent event) { 
       // where the items are dragged from 
       Table source = (Table) event.getTransferable().getSourceComponent(); 

       // where the items are dragged to 
       Table target = (Table) event.getTargetDetails().getTarget(); 

       // unique collection of dragged tasks 
       HashSet<Task> draggedTasks = new HashSet<>(); 

       // https://vaadin.com/api/com/vaadin/ui/Table.TableDragMode.html 
       // even in MULTIROW drag mode, the event contains only the row on which the drag started 
       draggedTasks.add((Task) event.getTransferable().getData("itemId")); 

       // we'll get the rest, if any, from the source table selection value 
       draggedTasks.addAll((Collection<Task>) source.getValue()); 

       // remove items from source table 
       draggedTasks.forEach(((Table) source)::removeItem); 

       // add items to destination table 
       target.addItems(draggedTasks); 
      } 

      @Override 
      public AcceptCriterion getAcceptCriterion() { 
       // accept drops only from specified tables, and prevent drops from the source table 
       return new SourceIs(acceptedSources); 
      } 
     }); 
    } 


    // basic bean for easy binding 
    public static class Task { 
     private String name; 
     private int id; 

     public Task(int id, String name) { 
      this.name = name; 
      this.id = id; 
     } 

     public String getName() { 
      return name; 
     } 

     public void setName(String name) { 
      this.name = name; 
     } 

     public int getId() { 
      return id; 
     } 

     public void setId(int id) { 
      this.id = id; 
     } 
    } 
} 

Ergebnis:

Vaadin table drag & drop