Я нашел пример перетаскивания для treetableview, но он работает только для одной строки. Я не смог найти никакой помощи для перетаскивания нескольких строк в дереве или таблице. Любая помощь будет оценена по достоинству.
Как реализовать перетаскивание нескольких строк в TreeTableView/TableView?
Ответы (1)
Все, что вам нужно сделать, чтобы разрешить перетаскивание нескольких строк в вашем примере, — это поместить в буфер обмена массив данных, а не только данные. Итак, в примере, который вы связали, вы бы сделали это вместо этого:
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();
}
});
Тогда вам просто нужно будет обработать все эти индексы в методе setOnDragDropped
:
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();
}
});
Конечно, для начала вам нужно будет включить множественный выбор в своей таблице. Это делается путем выполнения table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
.
person
Jonatan Stenbacka
schedule
24.08.2016
Просто примечание: я думаю, что реализация
ObservableList
не сериализуема, поэтому я думаю (но не проверял это), что это не удастся с исключением времени выполнения. Вероятно, вам нужно сделать cc.put(SERIALIZED_MIME_TYPE, new ArrayList<Integer>(getSelectionModel().getSelectedIndices()));
, а затем List<Integer> indexes = (List<Integer>) db.getContent(...);
.
- person James_D; 24.08.2016
с одной стороны он сериализуется и помещается в доску для перетаскивания. проблема возникает, когда вы получаете его обратно из dragboard. ArrayList‹Integer› content = (ArrayList‹Integer›) db.getContent(SERIALIZED_MIME_TYPE); Исключение в потоке Поток приложения JavaFX java.lang.ClassCastException: java.util.ArrayList не может быть приведен к java.lang.Integer в application.TableTreeViewApp.lambda$7(TableTreeViewApp.java:254)
- person Khanjee; 24.08.2016
На самом деле, после некоторого расследования кажется, что ошибка действительно возникает, когда вы помещаете ее в
ClipboardContent
, выполняя cc.put(SERIALIZED_MIME_TYPE, new ArrayList<Integer>(tree.getSelectionModel().getSelectedIndices()));
в row.setOnDragDetected
. Пока не знаю, почему так происходит, но попробую разобраться. Может быть, кто-то еще может объяснить это.
- person Jonatan Stenbacka; 24.08.2016
Вы должны принять это как принятый ответ, пока он действительно не сработает!
- person Jonatan Stenbacka; 24.08.2016
проблема решена, когда ArrayList вводится повсеместно. спасибо Джонатан Стенбака и Джеймс_Д
- person Khanjee; 24.08.2016
Не могли бы вы отредактировать мой ответ, указав правильный код, или опубликовать его здесь, в комментарии, чтобы я мог отредактировать свой ответ! :)
- person Jonatan Stenbacka; 24.08.2016
ваш ответ не нужно редактировать. Я делал это неправильно.
- person Khanjee; 24.08.2016