From 4406bd4aedd97c78833370c7d7b9934c95aefd27 Mon Sep 17 00:00:00 2001 From: Carlos Galindo Date: Fri, 13 Sep 2019 10:31:46 +0200 Subject: [PATCH] Table: added moving via drag and drop --- .../controller/DraggableRowFactory.java | 92 +++++++++++++++++++ .../jstudy/controller/TableController.java | 1 + 2 files changed, 93 insertions(+) create mode 100644 src/main/java/es/kauron/jstudy/controller/DraggableRowFactory.java diff --git a/src/main/java/es/kauron/jstudy/controller/DraggableRowFactory.java b/src/main/java/es/kauron/jstudy/controller/DraggableRowFactory.java new file mode 100644 index 0000000..c53bc70 --- /dev/null +++ b/src/main/java/es/kauron/jstudy/controller/DraggableRowFactory.java @@ -0,0 +1,92 @@ +package es.kauron.jstudy.controller; + +import javafx.collections.ObservableList; +import javafx.scene.control.TableRow; +import javafx.scene.control.TableView; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.DataFormat; +import javafx.scene.input.Dragboard; +import javafx.scene.input.TransferMode; + +import java.util.ArrayList; +import java.util.List; + +class DraggableRowFactory { + private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object"); + + private final ObservableList data; + private final List dragging = new ArrayList<>(); + + DraggableRowFactory(ObservableList data) { + this.data = data; + } + + TableRow generator(TableView table) { + TableRow row = new TableRow<>(); + row.setOnDragDetected((event) -> { + if (!row.isEmpty() && table.getItems().size() == data.size()) { + Integer index = row.getIndex(); + dragging.clear(); + dragging.addAll(table.getSelectionModel().getSelectedItems()); + Dragboard db = row.startDragAndDrop(TransferMode.MOVE); + ClipboardContent cc = new ClipboardContent(); + cc.put(SERIALIZED_MIME_TYPE, index); + db.setContent(cc); + event.consume(); + } + }); + row.setOnDragOver((event) -> { + Dragboard db = event.getDragboard(); + if (db.hasContent(SERIALIZED_MIME_TYPE)) { + if (row.getIndex() != (Integer) db.getContent(SERIALIZED_MIME_TYPE)) { + event.acceptTransferModes(TransferMode.COPY_OR_MOVE); + event.consume(); + } + } + }); + row.setOnDragDropped((event) -> { + Dragboard db = event.getDragboard(); + if (!db.hasContent(SERIALIZED_MIME_TYPE)) + return; + int dropIndex; + S item = null; + if (row.isEmpty()) { + dropIndex = table.getItems().size(); + } else { + dropIndex = row.getIndex(); + item = table.getItems().get(dropIndex); + } + int delta = 0; + if (item != null) { + while (dragging.contains(item)) { + delta = 1; + --dropIndex; + if (dropIndex < 0) { + item = null; + dropIndex = 0; + break; + } + item = table.getItems().get(dropIndex); + } + } + data.removeAll(dragging); + if (item != null) + dropIndex = table.getItems().indexOf(item) + delta; + else if (dropIndex != 0) + dropIndex = table.getItems().size(); + + table.getSelectionModel().clearSelection(); + + for (S s : dragging) { + data.add(dropIndex, s); + table.getSelectionModel().select(dropIndex); + dropIndex++; + } + + event.setDropCompleted(true); + dragging.clear(); + event.consume(); + }); + return row; + } +} diff --git a/src/main/java/es/kauron/jstudy/controller/TableController.java b/src/main/java/es/kauron/jstudy/controller/TableController.java index 99786d0..f2c8468 100644 --- a/src/main/java/es/kauron/jstudy/controller/TableController.java +++ b/src/main/java/es/kauron/jstudy/controller/TableController.java @@ -86,6 +86,7 @@ public class TableController implements Initializable { this.data = FXCollections.observableArrayList(list); this.filtered = data.filtered((item) -> true); this.parent = controller; + table.setRowFactory(new DraggableRowFactory<>(data)::generator); table.setItems(filtered); this.file = file; saved.set(file != null);