< prev index next >

src/java.desktop/share/classes/java/awt/Container.java

Print this page

        

@@ -42,10 +42,11 @@
 import java.io.PrintWriter;
 
 import java.lang.ref.WeakReference;
 import java.security.AccessController;
 
+import java.util.ArrayList;
 import java.util.EventListener;
 import java.util.HashSet;
 import java.util.Set;
 
 import javax.accessibility.*;

@@ -98,11 +99,11 @@
     /**
      * The components in this container.
      * @see #add
      * @see #getComponents
      */
-    private java.util.List<Component> component = new java.util.ArrayList<Component>();
+    private java.util.List<Component> component = new ArrayList<>();
 
     /**
      * Layout manager for this container.
      * @see #doLayout
      * @see #setLayout

@@ -2566,32 +2567,28 @@
     @Deprecated
     public Component locate(int x, int y) {
         if (!contains(x, y)) {
             return null;
         }
+        Component lightweight = null;
         synchronized (getTreeLock()) {
-            // Two passes: see comment in sun.awt.SunGraphicsCallback
-            for (int i = 0; i < component.size(); i++) {
-                Component comp = component.get(i);
-                if (comp != null &&
-                    !(comp.peer instanceof LightweightPeer)) {
+            // Optimized version of two passes:
+            // see comment in sun.awt.SunGraphicsCallback
+            for (final Component comp : component) {
                     if (comp.contains(x - comp.x, y - comp.y)) {
+                    if (!comp.isLightweight()) {
+                        // return heavyweight component as soon as possible
                         return comp;
                     }
+                    if (lightweight == null) {
+                        // save and return later the first lightweight component
+                        lightweight = comp;
                 }
             }
-            for (int i = 0; i < component.size(); i++) {
-                Component comp = component.get(i);
-                if (comp != null &&
-                    comp.peer instanceof LightweightPeer) {
-                    if (comp.contains(x - comp.x, y - comp.y)) {
-                        return comp;
                     }
                 }
-            }
-        }
-        return this;
+        return lightweight != null ? lightweight : this;
     }
 
     /**
      * Gets the component that contains the specified point.
      * @param      p   the point.

@@ -2691,56 +2688,58 @@
             }
         }
         return null;
     }
 
-    final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){
-        checkTreeLock();
+    final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled) {
+        // checkTreeLock(); commented for a performance reason
 
         if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
             return null;
         }
-
-        // Two passes: see comment in sun.awt.SunGraphicsCallback
-        for (int i = 0; i < component.size(); i++) {
-            Component comp = component.get(i);
-            if (comp != null &&
-                !(comp.peer instanceof LightweightPeer)) {
-                if (comp instanceof Container) {
-                    comp = ((Container)comp).findComponentAtImpl(x - comp.x,
-                                                                 y - comp.y,
-                                                                 ignoreEnabled);
+        Component lightweight = null;
+        // Optimized version of two passes:
+        // see comment in sun.awt.SunGraphicsCallback
+        for (final Component comp : component) {
+            final int x1 = x - comp.x;
+            final int y1 = y - comp.y;
+            if (!comp.contains(x1, y1)) {
+                continue; // fast path
+            }
+            if (!comp.isLightweight()) {
+                final Component child = getChildAt(comp, x1, y1, ignoreEnabled);
+                if (child != null) {
+                    // return heavyweight component as soon as possible
+                    return child;
+                }
                 } else {
-                    comp = comp.getComponentAt(x - comp.x, y - comp.y);
+                if (lightweight == null) {
+                    // save and return later the first lightweight component
+                    lightweight = getChildAt(comp, x1, y1, ignoreEnabled);
                 }
-                if (comp != null && comp.visible &&
-                    (ignoreEnabled || comp.enabled))
-                {
-                    return comp;
                 }
             }
+        return lightweight != null ? lightweight : this;
         }
-        for (int i = 0; i < component.size(); i++) {
-            Component comp = component.get(i);
-            if (comp != null &&
-                comp.peer instanceof LightweightPeer) {
+
+    /**
+     * Helper method for findComponentAtImpl. Finds a child component using
+     * findComponentAtImpl for Container and getComponentAt for Component.
+     */
+    private static Component getChildAt(Component comp, int x, int y,
+                                        boolean ignoreEnabled) {
                 if (comp instanceof Container) {
-                    comp = ((Container)comp).findComponentAtImpl(x - comp.x,
-                                                                 y - comp.y,
+            comp = ((Container) comp).findComponentAtImpl(x, y,
                                                                  ignoreEnabled);
                 } else {
-                    comp = comp.getComponentAt(x - comp.x, y - comp.y);
+            comp = comp.getComponentAt(x, y);
                 }
                 if (comp != null && comp.visible &&
-                    (ignoreEnabled || comp.enabled))
-                {
+                (ignoreEnabled || comp.enabled)) {
                     return comp;
                 }
-            }
-        }
-
-        return this;
+        return null;
     }
 
     /**
      * Locates the visible child component that contains the specified
      * point.  The top-most child component is returned in the case
< prev index next >