Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8092516

[SWT] FXCanvas doesn't deliver drag exited events after successful drop

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 8u5
    • Fix Version/s: 8u40
    • Component/s: javafx
    • Labels:

      Description

      DropTargetListener in FXCanvas$HostContainer class uses an "ignoreleave" flag to prevent drag leave after drop resulting in a javafx drag exited event. but this flag is never reset.

      i cannot attach a file so i'm pasting the test case code and fix.

      ==== TestCase.java ====

      import javafx.embed.swt.FXCanvas;
      import javafx.event.EventHandler;
      import javafx.event.EventType;
      import javafx.scene.Scene;
      import javafx.scene.control.TextArea;
      import javafx.scene.input.DragEvent;
      import javafx.scene.input.Dragboard;
      import javafx.scene.input.TransferMode;
      import org.eclipse.swt.SWT;
      import org.eclipse.swt.dnd.DND;
      import org.eclipse.swt.dnd.DragSource;
      import org.eclipse.swt.dnd.DragSourceAdapter;
      import org.eclipse.swt.dnd.DragSourceEvent;
      import org.eclipse.swt.dnd.TextTransfer;
      import org.eclipse.swt.dnd.Transfer;
      import org.eclipse.swt.layout.GridData;
      import org.eclipse.swt.layout.GridLayout;
      import org.eclipse.swt.widgets.Display;
      import org.eclipse.swt.widgets.Label;
      import org.eclipse.swt.widgets.Shell;

      /**
       * Demonstrates that {@link javafx.embed.swt.FXCanvas} does not deliver any
       * {@link javafx.scene.input.DragEvent#DRAG_EXITED} and
       * {@link javafx.scene.input.DragEvent#DRAG_EXITED_TARGET} after a successful
       * drop.
       * <p>
       * Steps to reproduce:
       * </p>
       * <ol>
       * <li>Start dragging from the left SWT label.</li>
       * <li>Drop into the JavaFX text area.</li>
       * <li>Start dragging from the left SWT label once more.</li>
       * <li>Drag over the JavaFX text area.</li>
       * <li>Drop into the right SWT label.</li>
       * </ol>
       */
      public class TestCase {

        public static void main( String[] args ) {
          final Display display = new Display();
          final Shell shell = new Shell(display);
          shell.setText("JavaFX/SWT DnD Interoperability");
          shell.setLayout(new GridLayout(3, false));


          final Label label1 = new Label(shell, SWT.CENTER | SWT.BORDER);
          label1.setText("Step 1: Drag from here.\nStep 3: Drag from here.");
          label1.setLayoutData(new GridData(GridData.FILL_BOTH));
          final Transfer[] transfers = new Transfer[]{TextTransfer.getInstance()};
          final DragSource dragSource = new DragSource(label1, DND.DROP_COPY);
          dragSource.setTransfer(transfers);
          dragSource.addDragListener(new DragSourceAdapter() {
            @Override
            public void dragSetData( final DragSourceEvent event ) {
              event.data = "Step 4: Drag text over text area.";
            }
          });


          final FXCanvas fxCanvas = new FXCanvas(shell, SWT.NONE);
          final TextArea textArea = new TextArea();
          textArea.setText("Step 2: Drop text here.");
          textArea.addEventFilter(DragEvent.ANY, new EventHandler<DragEvent>() {
            @Override
            public void handle( final DragEvent event ) {
              event.acceptTransferModes(TransferMode.COPY);

              final EventType<DragEvent> type = event.getEventType();
              if (type != DragEvent.DRAG_OVER) {
                System.out.println(type);
              }

              if (type == DragEvent.DRAG_DROPPED) {
                final Dragboard db = event.getDragboard();
                if (db != null) {
                  if (db.hasString()) {
                    textArea.setText(db.getString());
                  }
                }
                event.setDropCompleted(true);
              }

              event.consume();
            }
          });
          final Scene scene = new Scene(textArea);
          fxCanvas.setScene(scene);
          fxCanvas.setLayoutData(new GridData(GridData.FILL_BOTH));


          final Label label2 = new Label(shell, SWT.CENTER | SWT.BORDER);
          label2.setText(
                  "Step 5: Drop text here.\n" +
                  "(Will have not visible effect.)");
          label2.setLayoutData(new GridData(GridData.FILL_BOTH));


          shell.open();

          while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
              display.sleep();
            }
          }
          display.dispose();
        }
      }



      === FIX FXCanvas.java ====
      == method in anonymous listener in createDropTarget of HostContainer ==

      public void dragEnter(DropTargetEvent event) {

        ignoreLeave = false; // this is the fix

        dropTarget.setTransfer(getAllTransfers());
        detail = event.detail;
        operations = event.operations;
        dragOver (event, true, detail);
      }

        Attachments

          Activity

            People

            • Assignee:
              snorthov Steve Northover (Inactive)
              Reporter:
              srheinnecjfx Sebastian Rheinnecker (Inactive)
            • Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved:
                Imported:

                Time Tracking

                Estimated:
                Original Estimate - 5 minutes
                5m
                Remaining:
                Remaining Estimate - 5 minutes
                5m
                Logged:
                Time Spent - Not Specified
                Not Specified