1 /* 2 * Copyright (c) 2004, 2007, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 @test 26 @bug 5085626 27 @summary Exponential performance regression in AWT components (multiple mon) 28 @run main WPanelPeerPerf 29 */ 30 31 import java.awt.*; 32 import java.awt.event.*; 33 import javax.swing.*; 34 35 /** 36 * This test must be run on a multi-screen system. 37 * This test works by moving a Frame back and forth between the screens a few 38 * times. When the bug is active, the first move will overwhelm the EDT with 39 * recursive display change calls. The test fails if it takes too long to 40 * service the setLocation() calls and send componentMoved() events. 41 */ 42 public class WPanelPeerPerf { 43 44 private static final int NESTED_PANELS = 25; 45 private static final int ITERATIONS_PER_SCREEN = 3; 46 private static final int MAX_WAIT_PER_SCREEN = 2500; 47 private static final int PAUSE_BETWEEN_MOVES = 500; 48 49 50 private static Object showLock = new Object(); 51 52 private static Counter instance = null; 53 public static Counter getCounter() { 54 if (instance == null) { 55 instance = new Counter(); 56 } 57 return instance; 58 } 59 60 private static class Counter { 61 int counter; 62 Counter() { counter = 0; } 63 } 64 65 // This one is very slow! 66 public static void testAWT() { 67 // fail if only on one screen 68 int numScreens = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length; 69 if (numScreens < 2) { 70 System.err.println("Test must be run on a multiscreen system"); 71 return; 72 } 73 final Frame frame = new Frame("AWT WPanelPeerPerf"); 74 frame.addWindowListener(new WindowAdapter() { 75 public void windowClosing(WindowEvent ev) { 76 System.exit(0); 77 } 78 public void windowOpened(WindowEvent e) { 79 synchronized(showLock) { 80 showLock.notify(); 81 } 82 } 83 }); 84 frame.setLayout(new BorderLayout()); 85 Label label = new Label("Hello world"); 86 frame.add(label, BorderLayout.NORTH); 87 Panel panel = new Panel(new BorderLayout()); 88 Panel currentPanel = panel; 89 for (int i = 0; i < NESTED_PANELS; i++) { 90 Panel newPanel = new Panel(new BorderLayout()); 91 currentPanel.add(newPanel, BorderLayout.CENTER); 92 currentPanel = newPanel; 93 } 94 currentPanel.add(new Label("WPanelPeerPerf")); 95 frame.add(panel, BorderLayout.CENTER); 96 Button btn = new Button("OK"); 97 frame.add(btn, BorderLayout.SOUTH); 98 frame.pack(); 99 100 frame.addComponentListener(new ComponentAdapter() { 101 public void componentMoved(ComponentEvent e) { 102 System.out.println("Frame moved: "); 103 Counter ctr = getCounter(); 104 synchronized(ctr) { 105 ctr.counter++; 106 ctr.notify(); 107 } 108 } 109 }); 110 synchronized(showLock) { 111 try { 112 frame.setVisible(true); 113 showLock.wait(); 114 } 115 catch (InterruptedException e) { 116 e.printStackTrace(); 117 throw new RuntimeException("Problem with showLock"); 118 } 119 } 120 runTest(frame); 121 } 122 123 public static void runTest(Frame theFrame) { 124 System.out.println("Running test"); 125 GraphicsDevice[] devs = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); 126 Point[] points = new Point[devs.length]; 127 128 for (int i = 0; i < points.length; i++) { 129 Rectangle bounds = devs[i].getDefaultConfiguration().getBounds(); 130 points[i] = new Point(bounds.x + (bounds.width / 2), 131 bounds.y + (bounds.height / 2)); 132 System.out.println("Added point:" + points[i]); 133 } 134 135 final Frame localFrame = theFrame; 136 137 for (int n = 0; n < ITERATIONS_PER_SCREEN; n++) { 138 for (int i = 0; i < points.length; i++) { 139 final Point contextPoint = points[i]; 140 SwingUtilities.invokeLater(new Runnable() { 141 public void run() { 142 localFrame.setLocation(contextPoint); 143 } 144 }); 145 try { 146 Thread.sleep(PAUSE_BETWEEN_MOVES); 147 } 148 catch (InterruptedException e) { 149 System.out.println("Interrupted during iteration"); 150 } 151 } 152 } 153 Counter ctr = getCounter(); 154 synchronized(ctr) { 155 try { 156 if (ctr.counter < ITERATIONS_PER_SCREEN * devs.length) { 157 // If test hasn't finished, wait for maximum time 158 // If we get interrupted, test fails 159 ctr.wait((long)(ITERATIONS_PER_SCREEN * MAX_WAIT_PER_SCREEN * devs.length)); 160 System.out.println("after wait"); 161 if (ctr.counter < ITERATIONS_PER_SCREEN * devs.length) { 162 throw new RuntimeException("Waited too long for all the componentMoved()s"); 163 } 164 } 165 } 166 catch(InterruptedException e) { 167 e.printStackTrace(); 168 throw new RuntimeException("Wait interrupted - ???"); 169 } 170 System.out.println("Counter reads: " + ctr.counter); 171 } 172 173 } 174 public static void main(String[] args) { 175 testAWT(); 176 } 177 }