提交 a3799e58 编写于 作者: S serb

8071306: GUI perfomance are very slow compared java 1.6.0_45

Reviewed-by: azvegint, ant
上级 68510f4d
...@@ -1301,6 +1301,25 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -1301,6 +1301,25 @@ public abstract class Component implements ImageObserver, MenuContainer,
return visible && (parent == null || parent.isRecursivelyVisible()); return visible && (parent == null || parent.isRecursivelyVisible());
} }
/**
* Determines the bounds of a visible part of the component relative to its
* parent.
*
* @return the visible part of bounds
*/
private Rectangle getRecursivelyVisibleBounds() {
final Component container = getContainer();
final Rectangle bounds = getBounds();
if (container == null) {
// we are top level window or haven't a container, return our bounds
return bounds;
}
// translate the container's bounds to our coordinate space
final Rectangle parentsBounds = container.getRecursivelyVisibleBounds();
parentsBounds.setLocation(0, 0);
return parentsBounds.intersection(bounds);
}
/** /**
* Translates absolute coordinates into coordinates in the coordinate * Translates absolute coordinates into coordinates in the coordinate
* space of this component. * space of this component.
...@@ -1473,7 +1492,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -1473,7 +1492,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
ComponentPeer peer = this.peer; ComponentPeer peer = this.peer;
if (peer != null) { if (peer != null) {
peer.setEnabled(true); peer.setEnabled(true);
if (visible) { if (visible && !getRecursivelyVisibleBounds().isEmpty()) {
updateCursorImmediately(); updateCursorImmediately();
} }
} }
...@@ -1522,7 +1541,7 @@ public abstract class Component implements ImageObserver, MenuContainer, ...@@ -1522,7 +1541,7 @@ public abstract class Component implements ImageObserver, MenuContainer,
ComponentPeer peer = this.peer; ComponentPeer peer = this.peer;
if (peer != null) { if (peer != null) {
peer.setEnabled(false); peer.setEnabled(false);
if (visible) { if (visible && !getRecursivelyVisibleBounds().isEmpty()) {
updateCursorImmediately(); updateCursorImmediately();
} }
} }
......
...@@ -44,6 +44,7 @@ import java.io.PrintWriter; ...@@ -44,6 +44,7 @@ import java.io.PrintWriter;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.security.AccessController; import java.security.AccessController;
import java.util.ArrayList;
import java.util.EventListener; import java.util.EventListener;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
...@@ -100,7 +101,7 @@ public class Container extends Component { ...@@ -100,7 +101,7 @@ public class Container extends Component {
* @see #add * @see #add
* @see #getComponents * @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. * Layout manager for this container.
...@@ -2545,28 +2546,24 @@ public class Container extends Component { ...@@ -2545,28 +2546,24 @@ public class Container extends Component {
if (!contains(x, y)) { if (!contains(x, y)) {
return null; return null;
} }
Component lightweight = null;
synchronized (getTreeLock()) { synchronized (getTreeLock()) {
// Two passes: see comment in sun.awt.SunGraphicsCallback // Optimized version of two passes:
for (int i = 0; i < component.size(); i++) { // see comment in sun.awt.SunGraphicsCallback
Component comp = component.get(i); for (final Component comp : component) {
if (comp != null && if (comp.contains(x - comp.x, y - comp.y)) {
!(comp.peer instanceof LightweightPeer)) { if (!comp.isLightweight()) {
if (comp.contains(x - comp.x, y - comp.y)) { // return heavyweight component as soon as possible
return comp; return comp;
} }
} if (lightweight == null) {
} // save and return later the first lightweight component
for (int i = 0; i < component.size(); i++) { lightweight = comp;
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;
} }
/** /**
...@@ -2670,52 +2667,54 @@ public class Container extends Component { ...@@ -2670,52 +2667,54 @@ public class Container extends Component {
return null; return null;
} }
final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled){ final Component findComponentAtImpl(int x, int y, boolean ignoreEnabled) {
checkTreeLock(); // checkTreeLock(); commented for a performance reason
if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) { if (!(contains(x, y) && visible && (ignoreEnabled || enabled))) {
return null; return null;
} }
Component lightweight = null;
// Two passes: see comment in sun.awt.SunGraphicsCallback // Optimized version of two passes:
for (int i = 0; i < component.size(); i++) { // see comment in sun.awt.SunGraphicsCallback
Component comp = component.get(i); for (final Component comp : component) {
if (comp != null && final int x1 = x - comp.x;
!(comp.peer instanceof LightweightPeer)) { final int y1 = y - comp.y;
if (comp instanceof Container) { if (!comp.contains(x1, y1)) {
comp = ((Container)comp).findComponentAtImpl(x - comp.x, continue; // fast path
y - comp.y,
ignoreEnabled);
} else {
comp = comp.getComponentAt(x - comp.x, y - comp.y);
}
if (comp != null && comp.visible &&
(ignoreEnabled || comp.enabled))
{
return comp;
}
} }
} if (!comp.isLightweight()) {
for (int i = 0; i < component.size(); i++) { final Component child = getChildAt(comp, x1, y1, ignoreEnabled);
Component comp = component.get(i); if (child != null) {
if (comp != null && // return heavyweight component as soon as possible
comp.peer instanceof LightweightPeer) { return child;
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 && } else {
(ignoreEnabled || comp.enabled)) if (lightweight == null) {
{ // save and return later the first lightweight component
return comp; 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;
} }
/** /**
......
/*
* Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
import java.awt.Component;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Robot;
import javax.swing.JButton;
import javax.swing.SwingUtilities;
/**
* @test
* @bug 8071306
* @author Sergey Bylokhov
*/
public final class SetEnabledPerformance {
private static Frame frame;
private static void createAndShowGUI() {
frame = new Frame();
frame.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 0));
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
for (int i = 1; i < 10001; ++i) {
frame.add(new JButton("Button " + i));
}
frame.setVisible(true);
}
public static void main(final String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> createAndShowGUI());
final Robot robot = new Robot();
robot.waitForIdle();
robot.mouseMove(frame.getX() + 15, frame.getY() + 300);
robot.waitForIdle();
SwingUtilities.invokeAndWait(() -> {
long m = System.currentTimeMillis();
for (final Component comp : frame.getComponents()) {
comp.setEnabled(false);
}
m = System.currentTimeMillis() - m;
System.err.println("Disabled in " + m + " ms");
frame.dispose();
// we should be much faster, but leaves 1000 for the slow systems
if (m > 1000) {
throw new RuntimeException("Too slow");
}
});
}
}
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册