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

[SwingNode, DND]: drag-and-drop from JTable not working, startDrag never finishes

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • tbd
    • 8u60
    • javafx
    • x86
    • windows_8

      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
      Microsoft Windows [Version 6.3.9600]

      A DESCRIPTION OF THE PROBLEM :
      Very similar setup to JI-9028379

      Stage-> Scene embedding SwingNode with JTable. Register a DragGestureListener and upon "dragGestureRecognized" we start "startDrag".
      This results in the FXDnD$FXDragSourceContentPeer to start its own eventdispatchLoop that is supposed to only take as long as the drag operation.

      However it never returns. starting the example code (below) with parameter "swing" will run the same code without JavaFX in a JFrame. In this code drag works as expected. startDrag is entered and left once the dragoperation finishes

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      see example below

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      DragGestureEvent.startDrag should return when mouse is released and drag is finished
      ACTUAL -
      stays in eventdispatchloop of FX....Peer until forever

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      import java.awt.BorderLayout;
      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 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 SwingFXBug1b extends Application {

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

      public void startAsSwingOnly() {
      JFrame frame = new JFrame();
      frame.setBounds(0, 0, 200, 200);
      JPanel panel = new JPanel();
      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 boolean dragStarted = false;

      private void createDnDListener(JTable table) {
      DragGestureListener dgListener = new DragGestureListener() {
      @Override
      public void dragGestureRecognized(DragGestureEvent dge) {
      System.out.println("drag recognized...");
      // workaround for swingnode bug;
      if (!dragStarted) {
      dragStarted = true;
      dge.startDrag(java.awt.Cursor
      .getPredefinedCursor(java.awt.Cursor.HAND_CURSOR),
      new StringSelection("some string data"));
      dragStarted = false;
      System.out.println("drag finished");
      }
      }
      };

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

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

      CUSTOMER SUBMITTED WORKAROUND :
      no workaround known

            psadhukhan Prasanta Sadhukhan
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: