0

I found an example of drag drop for treetableview but it works for just one row. I couldn't find any help for drag drop of multiple rows in treetableview or tableview. Any help would be appreciated.

Example of single row drag drop

manlio
  • 18,345
  • 14
  • 76
  • 126
Khanjee
  • 3
  • 3

1 Answers1

2

All you need to do to modify allow dragging of multiple rows in your example is to put an array of data into the clipboard instead of just the data. So in the example you linked, you would do like this instead:

row.setOnDragDetected(event -> {
   if (!row.isEmpty()) {
      Dragboard db = row.startDragAndDrop(TransferMode.MOVE);
      db.setDragView(row.snapshot(null, null));
      ClipboardContent cc = new ClipboardContent();

      // Here you provide the ClipboardContent instance with the selected indexes instead of just one index.
      cc.put(SERIALIZED_MIME_TYPE, new ArrayList<Integer>(getSelectionModel().getSelectedIndices()));
      db.setContent(cc);
      event.consume();
   }
});

Then you would just have to handle all of those indexes in the setOnDragDropped method:

row.setOnDragDropped(event -> {
   Dragboard db = event.getDragboard();
   if (acceptable(db, row)) {
       // Get all indexes.
       ArrayList<Integer> indexes = (ArrayList<Integer>) db.getContent(SERIALIZED_MIME_TYPE);

       ObservableList<TreeItem> items = FXCollections.observableArrayList();    
       // Get the item on each index.
       for (int index : indexes) {
           items.add(tree.getTreeItem(index));
       }  

       // Modify the rest of the code commented out below to remove 
       // all items in your list and then add them your target.
       // item.getParent().getChildren().remove(item);
       // getTarget(row).getChildren().add(item);
       // event.setDropCompleted(true);
       // tree.getSelectionModel().select(item);

       event.consume();
   }            
});

Of course, you will have to enable multiple selection in your table to begin with. This is done by doing table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);.

Jonatan Stenbacka
  • 1,824
  • 2
  • 23
  • 48
  • Just a note: I think the implementation of `ObservableList` is not serializable, so I think (but haven't tested this) that this will fail with a runtime exception. You probably need to do `cc.put(SERIALIZED_MIME_TYPE, new ArrayList(getSelectionModel().getSelectedIndices()));` and then `List indexes = (List) db.getContent(...);`. – James_D Aug 24 '16 at 12:29
  • from one side it gets serialized and put it into the the dragboard. the problem arises when you getting it back from dragboard. ArrayList content = (ArrayList) db.getContent(SERIALIZED_MIME_TYPE); Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Integer at application.TableTreeViewApp.lambda$7(TableTreeViewApp.java:254) – Khanjee Aug 24 '16 at 13:48
  • Actually, after doing some investigating, it seems like the error actually occurs when you put it into the `ClipboardContent` by doing `cc.put(SERIALIZED_MIME_TYPE, new ArrayList(tree.getSelectionModel().getSelectedIndices()));` in `row.setOnDragDetected`. As of now I don't know why this happens, but I'll try to figure it out. Maybe someone else can explain it. – Jonatan Stenbacka Aug 24 '16 at 14:46
  • You should accept this as the accepted answer until it actually works by the way! – Jonatan Stenbacka Aug 24 '16 at 14:50
  • problem solved when ArrayList is introduced everywhere. thanks Jonatan Stenbacka and James_D – Khanjee Aug 24 '16 at 14:52
  • Could you please edit my answer with the correct code or post it here in the comment so I can edit my answer! :) – Jonatan Stenbacka Aug 24 '16 at 15:44
  • your answer doesn't need to edit. I was doing it the wrong way. – Khanjee Aug 24 '16 at 17:40