jdk/src/share/classes/java/awt/Container.java
changeset 21967 f09a60fb5967
parent 21957 97758de70fbd
parent 21787 11c9c9dfa450
child 24147 204ae465851d
--- a/jdk/src/share/classes/java/awt/Container.java	Tue Dec 03 21:22:14 2013 -0800
+++ b/jdk/src/share/classes/java/awt/Container.java	Tue Dec 03 23:09:17 2013 -0800
@@ -43,7 +43,6 @@
 
 import java.security.AccessController;
 
-import java.util.Arrays;
 import java.util.EventListener;
 import java.util.HashSet;
 import java.util.Set;
@@ -4427,6 +4426,7 @@
         stopListeningForOtherDrags();
         mouseEventTarget = null;
         targetLastEntered = null;
+        targetLastEnteredDT = null;
     }
 
     /**
@@ -4617,59 +4617,80 @@
     }
 
     /*
+     * Generates dnd enter/exit events as mouse moves over lw components
+     * @param targetOver       Target mouse is over (including native container)
+     * @param e                SunDropTarget mouse event in native container
+     */
+    private void trackDropTargetEnterExit(Component targetOver, MouseEvent e) {
+        int id = e.getID();
+        if (id == MouseEvent.MOUSE_ENTERED && isMouseDTInNativeContainer) {
+            // This can happen if a lightweight component which initiated the
+            // drag has an associated drop target. MOUSE_ENTERED comes when the
+            // mouse is in the native container already. To propagate this event
+            // properly we should null out targetLastEntered.
+            targetLastEnteredDT = null;
+        } else if (id == MouseEvent.MOUSE_ENTERED) {
+            isMouseDTInNativeContainer = true;
+        } else if (id == MouseEvent.MOUSE_EXITED) {
+            isMouseDTInNativeContainer = false;
+        }
+        targetLastEnteredDT = retargetMouseEnterExit(targetOver, e,
+                                                     targetLastEnteredDT,
+                                                     isMouseDTInNativeContainer);
+    }
+
+    /*
      * Generates enter/exit events as mouse moves over lw components
      * @param targetOver        Target mouse is over (including native container)
      * @param e                 Mouse event in native container
      */
     private void trackMouseEnterExit(Component targetOver, MouseEvent e) {
-        Component       targetEnter = null;
-        int             id = e.getID();
-
-        if (e instanceof SunDropTargetEvent &&
-            id == MouseEvent.MOUSE_ENTERED &&
-            isMouseInNativeContainer == true) {
-            // This can happen if a lightweight component which initiated the
-            // drag has an associated drop target. MOUSE_ENTERED comes when the
-            // mouse is in the native container already. To propagate this event
-            // properly we should null out targetLastEntered.
-            targetLastEntered = null;
-        } else if ( id != MouseEvent.MOUSE_EXITED &&
+        if (e instanceof SunDropTargetEvent) {
+            trackDropTargetEnterExit(targetOver, e);
+            return;
+        }
+        int id = e.getID();
+
+        if ( id != MouseEvent.MOUSE_EXITED &&
              id != MouseEvent.MOUSE_DRAGGED &&
              id != LWD_MOUSE_DRAGGED_OVER &&
-             isMouseInNativeContainer == false ) {
+                !isMouseInNativeContainer) {
             // any event but an exit or drag means we're in the native container
             isMouseInNativeContainer = true;
             startListeningForOtherDrags();
-        } else if ( id == MouseEvent.MOUSE_EXITED ) {
+        } else if (id == MouseEvent.MOUSE_EXITED) {
             isMouseInNativeContainer = false;
             stopListeningForOtherDrags();
         }
-
-        if (isMouseInNativeContainer) {
-            targetEnter = targetOver;
-        }
-
-        if (targetLastEntered == targetEnter) {
-                return;
-        }
-
-        if (targetLastEntered != null) {
-            retargetMouseEvent(targetLastEntered, MouseEvent.MOUSE_EXITED, e);
+        targetLastEntered = retargetMouseEnterExit(targetOver, e,
+                                                   targetLastEntered,
+                                                   isMouseInNativeContainer);
+    }
+
+    private Component retargetMouseEnterExit(Component targetOver, MouseEvent e,
+                                             Component lastEntered,
+                                             boolean inNativeContainer) {
+        int id = e.getID();
+        Component targetEnter = inNativeContainer ? targetOver : null;
+
+        if (lastEntered != targetEnter) {
+            if (lastEntered != null) {
+                retargetMouseEvent(lastEntered, MouseEvent.MOUSE_EXITED, e);
+            }
+            if (id == MouseEvent.MOUSE_EXITED) {
+                // consume native exit event if we generate one
+                e.consume();
+            }
+
+            if (targetEnter != null) {
+                retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
+            }
+            if (id == MouseEvent.MOUSE_ENTERED) {
+                // consume native enter event if we generate one
+                e.consume();
+            }
         }
-        if (id == MouseEvent.MOUSE_EXITED) {
-            // consume native exit event if we generate one
-            e.consume();
-        }
-
-        if (targetEnter != null) {
-            retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
-        }
-        if (id == MouseEvent.MOUSE_ENTERED) {
-            // consume native enter event if we generate one
-            e.consume();
-        }
-
-        targetLastEntered = targetEnter;
+        return targetEnter;
     }
 
     /*
@@ -4908,21 +4929,31 @@
     private transient Component mouseEventTarget;
 
     /**
-     * The last component entered
+     * The last component entered by the {@code MouseEvent}.
      */
     private transient Component targetLastEntered;
 
     /**
+     * The last component entered by the {@code SunDropTargetEvent}.
+     */
+    private transient Component targetLastEnteredDT;
+
+    /**
      * Indicates whether {@code mouseEventTarget} was removed and nulled
      */
     private transient boolean isCleaned;
 
     /**
-     * Is the mouse over the native container
+     * Is the mouse over the native container.
      */
     private transient boolean isMouseInNativeContainer = false;
 
     /**
+     * Is DnD over the native container.
+     */
+    private transient boolean isMouseDTInNativeContainer = false;
+
+    /**
      * This variable is not used, but kept for serialization compatibility
      */
     private Cursor nativeCursor;
@@ -4960,5 +4991,8 @@
         if (targetLastEntered == removedComponent) {
             targetLastEntered = null;
         }
+        if (targetLastEnteredDT == removedComponent) {
+            targetLastEnteredDT = null;
+        }
     }
 }