--- old/src/java.desktop/share/classes/java/awt/Container.java 2015-05-15 01:40:30.000000000 +0300 +++ new/src/java.desktop/share/classes/java/awt/Container.java 2015-05-15 01:40:30.000000000 +0300 @@ -44,6 +44,7 @@ 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; @@ -100,7 +101,7 @@ * @see #add * @see #getComponents */ - private java.util.List component = new java.util.ArrayList(); + private java.util.List component = new ArrayList<>(); /** * Layout manager for this container. @@ -2568,28 +2569,24 @@ 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)) { - if (comp.contains(x - comp.x, y - comp.y)) { + // 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; } - } - } - 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; + if (lightweight == null) { + // save and return later the first lightweight component + lightweight = comp; } } } } - return this; + return lightweight != null ? lightweight : this; } /** @@ -2693,52 +2690,54 @@ 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); - } else { - comp = comp.getComponentAt(x - comp.x, y - comp.y); - } - if (comp != null && comp.visible && - (ignoreEnabled || comp.enabled)) - { - return comp; - } + 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 } - } - 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); - } else { - comp = comp.getComponentAt(x - comp.x, y - comp.y); + if (!comp.isLightweight()) { + final Component child = getChildAt(comp, x1, y1, ignoreEnabled); + if (child != null) { + // return heavyweight component as soon as possible + return child; } - if (comp != null && comp.visible && - (ignoreEnabled || comp.enabled)) - { - return comp; + } else { + if (lightweight == null) { + // save and return later the first lightweight component + lightweight = getChildAt(comp, x1, y1, ignoreEnabled); } } } + return lightweight != null ? lightweight : this; + } - return this; + /** + * 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, y, + ignoreEnabled); + } else { + comp = comp.getComponentAt(x, y); + } + if (comp != null && comp.visible && + (ignoreEnabled || comp.enabled)) { + return comp; + } + return null; } /**