[prev in list] [next in list] [prev in thread] [next in thread] 

List:       openjdk-openjfx-dev
Subject:    drag&drop events?
From:       Magosányi Árpád <m4gw4s () gmail ! com>
Date:       2019-04-30 8:02:26
Message-ID: e49aed0b-52fa-8acb-1999-f86aff1c595c () gmail ! com
[Download RAW message or body]

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.


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic