Table: added moving via drag and drop

This commit is contained in:
Carlos Galindo 2019-09-13 10:31:46 +02:00
parent a599508fc3
commit 4406bd4aed
Signed by: kauron
GPG Key ID: 83E68706DEE119A3
2 changed files with 93 additions and 0 deletions

View File

@ -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<S> {
private static final DataFormat SERIALIZED_MIME_TYPE = new DataFormat("application/x-java-serialized-object");
private final ObservableList<S> data;
private final List<S> dragging = new ArrayList<>();
DraggableRowFactory(ObservableList<S> data) {
this.data = data;
}
TableRow<S> generator(TableView<S> table) {
TableRow<S> 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;
}
}

View File

@ -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);