drag&drop events?
Magosányi Árpád
m4gw4s at gmail.com
Tue Apr 30 08:02:26 UTC 2019
Hi list,
I am trying to implement drag&drop in a tree view. I actually did it. It
works. In 1/3rd of the times.
Otherwise there are times when relevant events do not arrive, and events
kick in from nowhere.
Specifically I don't see the dragDone event to fire, although I call
setDropCompleted(true) in the dragDropped event.
If I do hand testing, I just can't see much correlation between events
arriving and the mouse movements I do.
dragDropped events came out of nowhere, some cells receive
dragEnter/Exit/Over event, some not, the event source is set to
misterious values.
This is how I test (see
https://github.com/magwas/zenta3/blob/master/ui/src/test/java/org/rulez/demokracia/zenta3/editor/DragAndDropTest.java
for full code):
@Test
public void
when_the_drag_is_dropped_the_element_is_moved(
final FxRobot robot
) {
final ZentaTreeCell startCell = findCellFor(newElement);
robot.drag(startCell);
final ZentaTreeCell targetCell = findCellFor(thing);
final int targetIndex = targetCell.getIndex();
robot.moveTo(targetCell);
robot.dropTo(targetCell);
WaitForAsyncUtils.waitForFxEvents();
final ZentaTreeCell endCell = findCellFor(newElement);
assertEquals(targetIndex + 1, endCell.getIndex());
}
And these are the relevant lines of my TreeCell implementation (
https://github.com/magwas/zenta3/blob/master/ui/src/main/java/org/rulez/demokracia/zenta3/editor/tree/ZentaTreeCell.java
for full code):
public class ZentaTreeCell extends TreeCell<ZentaElement> {
public static final DataFormat ZENTA_FORMAT =
new DataFormat("Zenta Elements");
private final TreeView<ZentaElement> treeView;
public ZentaTreeCell(final TreeView<ZentaElement> view) {
super();
treeView = view;
setOnDragDetected((e) -> dragDetected(e));
setOnDragEntered((e) -> dragEntered(e));
setOnDragOver((e) -> dragOver(e));
setOnDragExited((e) -> dragExited(e));
setOnDragDropped((e) -> dragDropped(e));
setOnDragDone((e) -> dragDone(e));
}
private void dragDone(final DragEvent e) {
System.out.println("done\n\tat " + this + "\n\t event: " + e);
}
private void dragDropped(final DragEvent e) {
System.out.println("dropped\n\tat " + this + "\n\t event: " + e);
e.setDropCompleted(true);
e.getDragboard().clear();
e.consume();
getStyleClass().remove("dragtarget");
final ZentaTreeCell gestureSource = (ZentaTreeCell)
e.getGestureSource();
final ZentaTreeCell gestureTarget = (ZentaTreeCell)
e.getGestureTarget();
final TreeItem<ZentaElement> draggedItem = gestureSource.getTreeItem();
final TreeItem<ZentaElement> draggedItemParent =
draggedItem.getParent();
final TreeItem<ZentaElement> droppeditem = gestureTarget.getTreeItem();
final TreeItem<ZentaElement> droppedItemParent =
droppeditem.getParent();
final int indexInParent =
droppedItemParent.getChildren().indexOf(droppeditem);
draggedItemParent.getChildren().remove(draggedItem);
droppedItemParent.getChildren().add(indexInParent + 1, draggedItem);
treeView.getSelectionModel().select(draggedItem);
}
private void dragOver(final DragEvent e) {
System.out.println("over\n\tat " + this + "\n\t event: " + e);
e.acceptTransferModes(TransferMode.MOVE);
e.consume();
}
private void dragEntered(final DragEvent e) {
System.out.println("entered\n\tat " + this + "\n\t event: " + e);
getStyleClass().add("dragtarget");
e.consume();
}
private void dragExited(final DragEvent e) {
System.out.println("exited\n\tat " + this + "\n\t event: " + e);
getStyleClass().remove("dragtarget");
e.consume();
}
public void dragDetected(final MouseEvent e) {
System.out.println("detected\n\tat " + this + "\n\t event: " + e);
System.out.println("dragDetected");
final Dragboard dragBoard = startDragAndDrop(TransferMode.MOVE);
final Map<DataFormat, Object> map = new HashMap<>();
final ZentaElement item = getItem();
map.put(ZENTA_FORMAT, item);
System.out.println("item: " + item);
dragBoard.setContent(map);
e.consume();
}
@Override
public void updateItem(final ZentaElement item, final boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
final ZentaElement currentItem = getItem();
if (null != currentItem)
currentItem.removePropertyChangeListener((e) -> propertyChanged(e));
setItem(null);
} else {
setText(item.getName());
item.addPropertyChangeListener((e) -> propertyChanged(e));
}
setItem(item);
}
private void propertyChanged(final PropertyChangeEvent e) {
if (Folder.CHILDREN_PROPERTY.contentEquals(e.getPropertyName())) {
final TreeItem<ZentaElement> item =
new ZentaTreeItem((ZentaElement) e.getNewValue());
final TreeItem<ZentaElement> folderItem = getTreeItem();
if (!(folderItem instanceof ZentaTreeItem))
return;
final ZentaTreeItem folderCell = (ZentaTreeItem) folderItem;
folderCell.getChildren().add(item);
}
}
}
I guess I am missing something here, but after reading all the
documentation about drag&drop, I don't see what.
More information about the openjfx-dev
mailing list