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

[SwingNode, DND]: drag-and-drop from JTable not working, drag recognized twice

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: 8u60, 9
    • Fix Version/s: tbd
    • Component/s: javafx
    • Labels:
    • Subcomponent:
    • CPU:
      x86
    • OS:
      windows_8

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_60"
      Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
      Java HotSpot(TM) Client VM (build 25.60-b23, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Windows 8 64-bit with JDK8u60 32-bit

      A DESCRIPTION OF THE PROBLEM :
      We are creating a simple javafx Stage and Scene, placing a SwingNode within and embedding a Java Swing JTable. Then we attach DragGestureListener and DropTargetListener.

      When you start the example you see a window with that one table. Click on a row and drag and you get InvalidDndOperationException. The reason is that the DragGestureListener is invoked a second time with "dragGestureRecognized" while it is already in startDrag.

      You can start the attached example also with the parameter "swing" and then the same JTable setup is started without JavaFX Stage but with a JFrame. In this case the code behaves as expected. while in startDrag no second dragGesture is recognized.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      see example code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      no exception
      ACTUAL -
      InvalidDndOperationException

      ERROR MESSAGES/STACK TRACES THAT OCCUR :
      sun.awt.windows.WMouseDragGestureRecognizer@185ced1
      java.awt.dnd.DropTarget@91d3f2
      drag recognized...
      drag recognized...
      Exception in thread "AWT-EventQueue-0" java.awt.dnd.InvalidDnDOperationException: Drag and drop in progress
      at sun.awt.dnd.SunDragSourceContextPeer.setDragDropInProgress(SunDragSourceContextPeer.java:358)
      at java.awt.dnd.DragSource.startDrag(DragSource.java:301)
      at java.awt.dnd.DragSource.startDrag(DragSource.java:426)
      at java.awt.dnd.DragGestureEvent.startDrag(DragGestureEvent.java:238)
      at testfx.openjdk.bugreports.submit.SwingFXBug1a$3.dragGestureRecognized(SwingFXBug1a.java:105)
      at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(DragGestureRecognizer.java:361)
      at sun.awt.windows.WMouseDragGestureRecognizer.mouseDragged(WMouseDragGestureRecognizer.java:218)
      at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:320)
      at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:319)
      at java.awt.Component.processMouseMotionEvent(Component.java:6583)
      at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:3342)
      at java.awt.Component.processEvent(Component.java:6304)
      at java.awt.Container.processEvent(Container.java:2236)
      at java.awt.Component.dispatchEventImpl(Component.java:4891)
      at java.awt.Container.dispatchEventImpl(Container.java:2294)
      at java.awt.Component.dispatchEvent(Component.java:4713)
      at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
      at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4542)
      at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
      at java.awt.Container.dispatchEventImpl(Container.java:2280)
      at java.awt.Window.dispatchEventImpl(Window.java:2750)
      at java.awt.Component.dispatchEvent(Component.java:4713)
      at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
      at java.awt.EventQueue.access$500(EventQueue.java:97)
      at java.awt.EventQueue$3.run(EventQueue.java:709)
      at java.awt.EventQueue$3.run(EventQueue.java:703)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
      at java.awt.EventQueue$4.run(EventQueue.java:731)
      at java.awt.EventQueue$4.run(EventQueue.java:729)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
      at java.awt.WaitDispatchSupport$2.run(WaitDispatchSupport.java:182)
      at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:229)
      at java.awt.WaitDispatchSupport$4.run(WaitDispatchSupport.java:227)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.awt.WaitDispatchSupport.enter(WaitDispatchSupport.java:227)
      at javafx.embed.swing.FXDnD$FXDragSourceContextPeer.startDrag(FXDnD.java:343)
      at sun.awt.dnd.SunDragSourceContextPeer.startDrag(SunDragSourceContextPeer.java:135)
      at java.awt.dnd.DragSource.startDrag(DragSource.java:321)
      at java.awt.dnd.DragSource.startDrag(DragSource.java:426)
      at java.awt.dnd.DragGestureEvent.startDrag(DragGestureEvent.java:238)
      at testfx.openjdk.bugreports.submit.SwingFXBug1a$3.dragGestureRecognized(SwingFXBug1a.java:105)
      at java.awt.dnd.DragGestureRecognizer.fireDragGestureRecognized(DragGestureRecognizer.java:361)
      at sun.awt.windows.WMouseDragGestureRecognizer.mouseDragged(WMouseDragGestureRecognizer.java:218)
      at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:320)
      at java.awt.AWTEventMulticaster.mouseDragged(AWTEventMulticaster.java:319)
      at java.awt.Component.processMouseMotionEvent(Component.java:6583)
      at javax.swing.JComponent.processMouseMotionEvent(JComponent.java:3342)
      at java.awt.Component.processEvent(Component.java:6304)
      at java.awt.Container.processEvent(Container.java:2236)
      at java.awt.Component.dispatchEventImpl(Component.java:4891)
      at java.awt.Container.dispatchEventImpl(Container.java:2294)
      at java.awt.Component.dispatchEvent(Component.java:4713)
      at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
      at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4542)
      at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
      at java.awt.Container.dispatchEventImpl(Container.java:2280)
      at java.awt.Window.dispatchEventImpl(Window.java:2750)
      at java.awt.Component.dispatchEvent(Component.java:4713)
      at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
      at java.awt.EventQueue.access$500(EventQueue.java:97)
      at java.awt.EventQueue$3.run(EventQueue.java:709)
      at java.awt.EventQueue$3.run(EventQueue.java:703)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
      at java.awt.EventQueue$4.run(EventQueue.java:731)
      at java.awt.EventQueue$4.run(EventQueue.java:729)
      at java.security.AccessController.doPrivileged(Native Method)
      at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
      at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
      at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
      at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
      at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
      at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
      at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)


      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BorderLayout;
      import java.awt.Dimension;
      import java.awt.datatransfer.StringSelection;
      import java.awt.dnd.DnDConstants;
      import java.awt.dnd.DragGestureEvent;
      import java.awt.dnd.DragGestureListener;
      import java.awt.dnd.DragSource;
      import java.awt.dnd.DropTarget;
      import java.awt.dnd.DropTargetAdapter;
      import java.awt.dnd.DropTargetDropEvent;
      import java.awt.dnd.DropTargetListener;

      import javafx.application.Application;
      import javafx.beans.InvalidationListener;
      import javafx.beans.Observable;
      import javafx.embed.swing.SwingNode;
      import javafx.scene.Scene;
      import javafx.scene.layout.BorderPane;
      import javafx.stage.Stage;

      import javax.swing.JComponent;
      import javax.swing.JFrame;
      import javax.swing.JPanel;
      import javax.swing.JTable;
      import javax.swing.SwingUtilities;
      import javax.swing.table.DefaultTableModel;

      public class SwingFXBug1a extends Application {

      public static void main(String[] args) {
      if (args.length > 0) {
      if (args[0].equals("swing")) {
      new SwingFXBug1a().startAsSwingOnly();
      }
      } else {
      Application.launch(args);
      }
      }

      public void startAsSwingOnly() {
      JFrame frame = new JFrame();
      JPanel panel = new JPanel();
      panel.setPreferredSize(new Dimension(200, 200));
      createContent(panel);
      frame.getContentPane().add(panel, BorderLayout.CENTER);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setTitle("Pure Swing");
      frame.pack();
      frame.setVisible(true);
      }

      @Override
      public void start(Stage stage) {

      final SwingNode swingNode = new SwingNode();
      JPanel panel = new JPanel();

      createContent(panel);
      swingNode.setContent(panel);
      BorderPane pane = new BorderPane();
      pane.setCenter(swingNode);

      stage.setTitle("Swing in JavaFX");
      stage.setScene(new Scene(pane, 250, 150));
      stage.onCloseRequestProperty().addListener(new InvalidationListener() {
      @Override
      public void invalidated(Observable observable) {
      System.exit(0);
      }
      });
      stage.show();
      }

      private void createContent(final JComponent component) {
      SwingUtilities.invokeLater(new Runnable() {

      @Override
      public void run() {

      DefaultTableModel tm = new DefaultTableModel();
      tm.addColumn("column-1");
      JTable table = new JTable(tm);
      tm.addRow(new String[] { "data-1" });
      tm.addRow(new String[] { "data-2" });
      tm.addRow(new String[] { "data-3" });
      tm.addRow(new String[] { "data-4" });

      // table.setTransferHandler(new TableRowTransferHandler(table));
      table.setDragEnabled(false);

      createDnDListener(table);

      component.add(table);
      }
      });
      }

      private void createDnDListener(JTable table) {
      DragGestureListener dgListener = new DragGestureListener() {
      @Override
      public void dragGestureRecognized(DragGestureEvent dge) {
      System.out.println("drag recognized...");
      dge.startDrag(java.awt.Cursor
      .getPredefinedCursor(java.awt.Cursor.HAND_CURSOR),
      new StringSelection("some string data"));
      System.out.println("drag finished");
      }
      };

      DropTargetListener dropListener = new DropTargetAdapter() {

      @Override
      public void drop(DropTargetDropEvent dtde) {
      // never gets here
      System.out.println("drop... " + dtde.getTransferable());
      }
      };

      DragSource dragSource = new DragSource();
      Object dragRecognizer = dragSource.createDefaultDragGestureRecognizer(
      table, DnDConstants.ACTION_COPY_OR_MOVE, dgListener);
      DropTarget dropTarget = new DropTarget(table, dropListener);
      System.out.println(dragRecognizer);
      System.out.println(dropTarget);

      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      as a workaround the application could track when startDrag is entered and prevent a second excution itself.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                psadhukhan Prasanta Sadhukhan
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                1 Vote for this issue
                Watchers:
                4 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: