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

dragEnter/dragExit methods of DragSourceListener fire without reaching target

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 1.4.2
    • Fix Version/s: 5.0
    • Component/s: client-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      tiger
    • CPU:
      x86
    • OS:
      windows_xp

      Description



      Name: rmT116609 Date: 06/04/2003


      FULL PRODUCT VERSION :
      java version "1.4.2-beta"
      Java (TM) 2 Runtime Environment, Standard Edition (build 1.4.2-beta-b19)
      Java HotSpot(TM) Client VM (build 1.4.2-beta-b19, mixed mode)

      FULL OS VERSION :
      Windows XP Professional, Version 2002

      A DESCRIPTION OF THE PROBLEM :
      dragEnter and dragExit methods of DragSourceListener fire continuously as the dragging action occurs. They should fire only when the drop target is reached, but in 1.4.2-beta it happens even when the drop target is not designated.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Compile the submitted code. Launch the program (Test.main()). Start dragging action in the displayed window. The debugging output tracing the methods firing continuously will be shown in the console.

      Running the same app against 1.4.1 shows dragEnter and dragExit methods firing only when the drag action ends (mouse released).



      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      In the given test case, the dragEnter and dragExit methods should fire only when the mouse is released.
      ACTUAL -
      The dragEnter and dragExit methods fire continuously, as the mouse drags across the window.

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      // file Test.java

      import java.awt.*;
      import javax.swing.*;

      public class Test
      {
      private Controller controller;

      public Test()
      {
      controller = new Controller();
      }

      public static void main(String args[])
      {
      try
      {
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
      if (System.getProperty("os.name").startsWith("Windows"))
      UIManager.getDefaults().put("ScrollBar.track",
      new javax.swing.plaf.ColorUIResource (224, 224, 224));
      UIManager.put("ToolTip.font",new Font("SansSerif",Font.PLAIN,10));
      }
      catch (Exception exc) { System.out.println("Error loading L&F: " + exc); }
      new Test();
      }
      }

      // file Controller.java

      import java.awt.*;
      import java.awt.dnd.*;
      import java.awt.datatransfer.*;
      import javax.swing.*;

      public class Controller implements DragGestureListener, DragSourceListener, DragSourceMotionListener, Transferable
      {
      private JFrame frame;
      private Container contentPane;
      private Rectangle windowRect;
      private Font plainFont, boldFont;
      private TransparentWindow cache;
      private DataFlavor[] dummyDataFlavors = { new DataFlavor(String.class, "") };

      public Controller()
      {
      frame = new JFrame();
      frame.addNotify();
      frame.pack();
      boldFont = new Font("SansSerif",Font.BOLD,18);
      contentPane = frame.getContentPane();
      contentPane.setLayout(null);
      frame.setSize(350, 250);
      frame.validate();
      windowRect = frame.getBounds();
      createViews();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
      frame.doLayout();
      cache = new TransparentWindow();
      }

      public void createViews()
      {
      /*
      ** Drag source
      */
      DragSourceLabel dragSource = new DragSourceLabel("Drag from here...");
      dragSource.setFont(boldFont);
      dragSource.setSize(dragSource.getPreferredSize());
      dragSource.setLocation(20, 20);
      contentPane.add(dragSource);
      DragSource ds = DragSource.getDefaultDragSource();
      ds.addDragSourceMotionListener(this);
      DragGestureRecognizer dgr = ds.createDefaultDragGestureRecognizer(dragSource, DnDConstants.ACTION_MOVE, this);
      dragSource.setDragGestureRecognizer(dgr);
      /*
      ** Drag target
      */
      JLabel dragTarget = new JLabel("...to here");
      dragTarget.setFont(boldFont);
      dragTarget.setSize(dragTarget.getPreferredSize());
      dragTarget.setLocation(contentPane.getWidth() - dragTarget.getWidth() - 20, contentPane.getHeight() - dragTarget.getHeight() - 20);
      contentPane.add(dragTarget);
      }

      public void dragGestureRecognized(DragGestureEvent dge)
      {
      System.out.println("dragGestureRecognized");
      Point location = dge.getDragOrigin();
      SwingUtilities.convertPointToScreen(location, dge.getComponent());
      cache.setLocation(location);
      cache.setVisible(true);
      dge.startDrag(null, this, this);
      }

      public void dragDropEnd(DragSourceDropEvent dsde)
      {
      System.out.println("dragDropEnd");
      cache.setVisible(false);
      }

      public void dropActionChanged(DragSourceDragEvent dsde) {}
      public void dragEnter(DragSourceDragEvent dsde)
      {
      System.out.println("dragEnter");
      }

      public void dragExit(DragSourceEvent dse)
      {
      System.out.println("dragExit");
      }

      public void dragMouseMoved(DragSourceDragEvent dsde)
      {
      Point origin = dsde.getLocation();
      cache.setLocation(origin);
      }

      public void dragOver(DragSourceDragEvent dsde) {}
      public Object getTransferData(DataFlavor flavor) { return null; }
      public DataFlavor[] getTransferDataFlavors() { return (dummyDataFlavors); }
      public boolean isDataFlavorSupported(DataFlavor flavor) { return (true); }
      }

      // file DragSourceLabel.java

      import javax.swing.*;
      import java.util.*;
      import java.awt.event.*;
      import java.awt.dnd.*;

      public class DragSourceLabel extends JLabel
      {
      protected DragGestureListener dgl;
      protected DragGestureRecognizer dgr;

      public DragSourceLabel(String text)
      {
      super(text);
      }

      public void setDragGestureRecognizer(DragGestureRecognizer dgr)
      {
      this.dgr = dgr;
      }

      protected void processMouseEvent(MouseEvent e)
      {
      boolean suppressDND = false;
      switch (e.getID())
      {
      case MouseEvent.MOUSE_PRESSED:
      suppressDND = true;
      break;
      case MouseEvent.MOUSE_RELEASED:
      suppressDND = true;
      break;
      }
      if (suppressDND)
      {
      EventListener el[] = getListeners(DragGestureListener.class);
      for (int i = 0; i < el.length; i++)
      dgr.removeDragGestureListener((DragGestureListener) el[i]);
      super.processMouseEvent(e);
      for (int i = 0; i < el.length; i++)
      {
      try { dgr.addDragGestureListener((DragGestureListener) el[i]); }
      catch (TooManyListenersException exc) { System.out.println(exc); }
      }
      }
      else
      super.processMouseEvent(e);
      }
      }

      // file TransparentWindow.java

      import java.awt.*;
      import java.awt.image.*;
      import javax.swing.*;

      public class TransparentWindow extends JWindow
      {
      private Container contentPane;
      private BufferedImage currentImage, baseImage;
      private Image tileImage[];
      private Rectangle baseRect, tile[];
      private Point origin, baseOrigin;
      private Robot r;
      private Font boldFont;
      private boolean drawBackgroundOnly;

      public TransparentWindow()
      {
      super(new Frame());
      tileImage = new Image[2];
      tileImage[0] = null;
      tileImage[1] = null;
      baseOrigin = new Point();
      pack();
      setSize(100, 100);
      boldFont = new Font("SansSerif",Font.BOLD,16);
      validate();
      try
      {
      r = new Robot();
      }
      catch (AWTException awe)
      {
      System.out.println("robot excepton occurred");
      }
      }

      protected void grabCurrentImage()
      {
      currentImage = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_RGB);
      Graphics g = currentImage.getGraphics();
      drawBackgroundOnly = true;
      paint(g);
      drawBackgroundOnly = false;
      g.dispose();
      }

      public void capture()
      {
      baseRect = getBounds();
      baseImage = r.createScreenCapture(baseRect);
      }

      public void setVisible(boolean flag)
      {
      if (flag)
      {
      capture();
      grabCurrentImage();
      }
      super.setVisible(flag);
      }

      public void setLocation(Point loc)
      {
      /*
      ** Calculate tiled rectangles
      */
      Rectangle oldFrame = getBounds();
      Rectangle newFrame = new Rectangle(loc.x, loc.y, oldFrame.width, oldFrame.height);
      baseRect = oldFrame.intersection(newFrame);
      tile = SwingUtilities.computeDifference(newFrame, oldFrame);
      /*
      ** Get base image from the captured ImageBuffer
      */
      if (baseRect.width > 0 && baseRect.height > 0)
      baseImage = currentImage.getSubimage(baseRect.x - oldFrame.x, baseRect.y - oldFrame.y, baseRect.width, baseRect.height);
      else
      baseImage = null;
      /*
      ** Capture tile images from the screen
      */
      tileImage[0] = null;
      tileImage[1] = null;
      for (int i = 0; i < tile.length; i++)
      {
      if (!tile[i].isEmpty())
      tileImage[i] = r.createScreenCapture(tile[i]);
      }
      /*
      ** Translate the rectangles to the origin of the new frame
      */
      baseRect.x -= newFrame.x;
      baseRect.y -= newFrame.y;
      for (int i = 0; i < tile.length; i++)
      {
      if (!tile[i].isEmpty())
      {
      tile[i].x -= newFrame.x;
      tile[i].y -= newFrame.y;
      }
      }
      super.setVisible(false);
      super.setLocation(loc);
      grabCurrentImage();
      super.setVisible(true);
      }

      public void paint(Graphics g)
      {
      super.paintComponents(g);
      if (baseImage != null)
      g.drawImage(baseImage, baseRect.x, baseRect.y, null);
      for (int i = 0; i < tile.length; i++)
      {
      if (tileImage[i] != null)
      g.drawImage(tileImage[i], tile[i].x, tile[i].y, null);
      }
      if (drawBackgroundOnly)
      return;
      g.setColor(Color.black);
      g.setFont(boldFont);
      g.drawString("Hello there", 5, 50);
      Rectangle rect = getBounds();
      g.setColor(Color.red);
      g.drawRect(0,0,rect.width - 1,rect.height - 1);
      }
      }
      ---------- END SOURCE ----------

      Release Regression From : 1.4.1_03
      The above release value was the last known release where this
      bug was known to work. Since then there has been a regression.

      (Review ID: 186668)
      ======================================================================

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                agerasimsunw Alexander Gerasimov (Inactive)
                Reporter:
                rmandalasunw Ranjith Mandala (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: