1 /* 2 * Copyright (c) 2014, 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 import java.awt.*; 25 import java.util.ArrayList; 26 import javax.swing.*; 27 28 /* 29 @test 30 @summary Toplevel should be correctly positioned as relative to a component: 31 so that their centers coincide 32 or, if the component is hidden, centered on the screen. 33 @bug 8036915 34 @library ../../../../lib/testlibrary 35 @build ExtendedRobot 36 @run main/timeout=1200 SetLocationRelativeToTest 37 @key randomness 38 */ 39 40 public class SetLocationRelativeToTest { 41 private static int delay = 500; 42 private static boolean testEverything = false;// NB: change this to true to test everything 43 java.util.List<Window> awtToplevels = new ArrayList<Window>(); 44 java.util.List<Window> swingToplevels = new ArrayList<Window>(); 45 java.util.List<Window> allToplevels = new ArrayList<Window>(); 46 java.util.List<Component> awtComponents = new ArrayList<Component>(); 47 java.util.List<Component> swingComponents = new ArrayList<Component>(); 48 java.util.List<Component> allComponents = new ArrayList<Component>(); 49 Label placeholder = new Label(); 50 JLabel jplaceholder = new JLabel(); 51 JFrame jcontainer; 52 public SetLocationRelativeToTest() { 53 Frame frame = new Frame("Frame"); 54 frame.setSize(200,100); 55 Frame uframe = new Frame("U.Frame"); 56 uframe.setUndecorated(true); 57 uframe.setSize(200,100); 58 Window window = new Window(frame); 59 window.setSize(200,100); 60 Dialog dialog = new Dialog(frame, "Dialog"); 61 dialog.setSize(200,100); 62 awtToplevels.add(frame); 63 awtToplevels.add(uframe); 64 awtToplevels.add(window); 65 awtToplevels.add(dialog); 66 67 awtComponents.add(new TextArea("Am a TextArea")); 68 awtComponents.add(new TextField("Am a TextField")); 69 awtComponents.add(new Button("Press")); 70 awtComponents.add(new Label("Label")); 71 Choice aChoice = new Choice(); 72 aChoice.add("One"); 73 aChoice.add("Two"); 74 awtComponents.add(aChoice); 75 awtComponents.add(new Canvas()); 76 awtComponents.add(new List(4)); 77 awtComponents.add(new Checkbox("Me CheckBox")); 78 awtComponents.add(new Scrollbar()); 79 80 swingComponents.add(new JTextArea("Am a JTextArea")); 81 swingComponents.add(new JTextField("Am a JTextField")); 82 swingComponents.add(new JButton("Press")); 83 swingComponents.add(new JLabel("JLabel")); 84 JComboBox jcombo = new JComboBox(); 85 swingComponents.add(jcombo); 86 swingComponents.add(new JPanel()); 87 swingComponents.add(new JList()); 88 swingComponents.add(new JCheckBox("Me JCheckBox")); 89 swingComponents.add(new JScrollBar()); 90 } 91 92 public static void main(String args[]) { 93 SetLocationRelativeToTest test = new SetLocationRelativeToTest(); 94 test.doAWTTest(true); 95 test.doAWTTest(false); 96 try { 97 test.doSwingTest(true); 98 test.doSwingTest(false); 99 }catch(InterruptedException ie) { 100 ie.printStackTrace(); 101 }catch(java.lang.reflect.InvocationTargetException ite) { 102 ite.printStackTrace(); 103 throw new RuntimeException("InvocationTarget?"); 104 } 105 return; 106 } 107 108 // In regular testing, we select just few components to test 109 // randomly. If full testing required, select many ("all"). 110 void selectObjectsToTest(boolean doSwing) { 111 allToplevels.clear(); 112 allComponents.clear(); 113 if(testEverything) { 114 allToplevels.addAll(0, awtToplevels); 115 allComponents.addAll(0, awtComponents); 116 if(doSwing) { 117 allToplevels.addAll(allToplevels.size(), swingToplevels); 118 allComponents.addAll(allComponents.size(), swingComponents); 119 } 120 }else{ 121 //select a random of each 122 int i = (int)(java.lang.Math.random()*awtToplevels.size()); 123 allToplevels.add(awtToplevels.get(i)); 124 i = (int)(java.lang.Math.random()*awtComponents.size()); 125 allComponents.add(awtComponents.get(i)); 126 if(doSwing) { 127 i = (int)(java.lang.Math.random()*swingToplevels.size()); 128 allToplevels.add(swingToplevels.get(i)); 129 i = (int)(java.lang.Math.random()*swingComponents.size()); 130 allComponents.add(swingComponents.get(i)); 131 } 132 } 133 } 134 135 // create Frame, add an AWT component to it, 136 // hide it (or not) and position a new toplevel 137 // relativeTo 138 void doAWTTest(boolean isHidden) { 139 boolean res; 140 ExtendedRobot robot; 141 try { 142 robot = new ExtendedRobot(); 143 }catch(Exception ex) { 144 ex.printStackTrace(); 145 throw new RuntimeException("Failed: "+ex.getMessage()); 146 } 147 Frame container = new Frame("Frame"); 148 container.setBounds(100,100,300,300); 149 container.setLayout(new GridLayout(3,1)); 150 container.add(placeholder); 151 container.setVisible(true); 152 selectObjectsToTest(false); 153 for(Component c: allComponents) { 154 placeholder.setText((isHidden ? "Hidden: " : "Below is ")+ c.getClass().getName()); 155 c.setVisible(true); 156 container.add(c); 157 container.doLayout(); 158 if(isHidden) { 159 c.setVisible(false); 160 } 161 robot.waitForIdle(delay); 162 for(Window w: allToplevels) { 163 w.setLocationRelativeTo(c); 164 w.setVisible(true); 165 robot.waitForIdle(delay); 166 res = compareLocations(w, c, robot); 167 System.out.println(c.getClass().getName()+" \t: "+w.getClass().getName()+ 168 ((w instanceof Frame) && (((Frame)w).isUndecorated()) ? " undec\t\t:" : "\t\t:")+" "+ 169 (res ? "" : "Failed")); 170 if(!res) { 171 throw new RuntimeException("Test failed."); 172 } 173 w.dispose(); 174 } 175 container.remove(c); 176 robot.waitForIdle(delay); 177 } 178 container.dispose(); 179 } 180 181 // Create JFrame, add an AWT or Swing component to it, 182 // hide it (or not) and position a new toplevel 183 // relativeTo 184 void doSwingTest(boolean isHidden) throws InterruptedException, 185 java.lang.reflect.InvocationTargetException { 186 boolean res; 187 ExtendedRobot robot; 188 try { 189 robot = new ExtendedRobot(); 190 }catch(Exception ex) { 191 ex.printStackTrace(); 192 throw new RuntimeException("Failed: "+ex.getMessage()); 193 } 194 195 EventQueue.invokeAndWait( () -> { 196 JFrame jframe = new JFrame("jframe"); 197 jframe.setSize(200,100); 198 swingToplevels.add(jframe); 199 JFrame ujframe = new JFrame("ujframe"); 200 ujframe.setSize(200,100); 201 ujframe.setUndecorated(true); 202 swingToplevels.add(ujframe); 203 JWindow jwin = new JWindow(); 204 jwin.setSize(200,100); 205 swingToplevels.add(jwin); 206 JDialog jdia = new JDialog((Frame)null, "JDialog"); 207 jdia.setSize(200,100); 208 swingToplevels.add(jdia); 209 jcontainer = new JFrame("JFrame"); 210 jcontainer.setBounds(100,100,300,300); 211 jcontainer.setLayout(new GridLayout(3,1)); 212 jcontainer.add(jplaceholder); 213 jcontainer.setVisible(true); 214 selectObjectsToTest(true); 215 }); 216 robot.waitForIdle(delay); 217 218 for(Component c: allComponents) { 219 EventQueue.invokeAndWait( () -> { 220 jplaceholder.setText((isHidden ? "Hidden: " : "Below is: ")+ c.getClass().getName()); 221 c.setVisible(true); 222 jcontainer.add(c); 223 jcontainer.doLayout(); 224 if(isHidden) { 225 c.setVisible(false); 226 } 227 }); 228 robot.waitForIdle(delay); 229 for(Window w: allToplevels) { 230 EventQueue.invokeAndWait( () -> { 231 w.setLocationRelativeTo(c); 232 w.setVisible(true); 233 }); 234 robot.waitForIdle(delay); 235 res = compareLocations(w, c, robot); 236 System.out.println(c.getClass().getName()+" \t: "+w.getClass().getName()+ 237 ((w instanceof Frame) && (((Frame)w).isUndecorated()) ? " undec\t\t:" : "\t\t:")+" "+ 238 (res ? "" : "Failed")); 239 EventQueue.invokeAndWait( () -> { 240 w.dispose(); 241 }); 242 robot.waitForIdle(); 243 if(!res) { 244 throw new RuntimeException("Test failed."); 245 } 246 } 247 EventQueue.invokeAndWait( () -> { 248 jcontainer.remove(c); 249 }); 250 robot.waitForIdle(delay); 251 } 252 EventQueue.invokeAndWait( () -> { 253 jcontainer.dispose(); 254 }); 255 } 256 257 // Check, finally, if w either is concentric with c 258 // or sits in the center of the screen (if c is hidden) 259 boolean compareLocations(final Window w, final Component c, ExtendedRobot robot) { 260 final Point pc = new Point(); 261 final Point pw = new Point(); 262 try { 263 EventQueue.invokeAndWait( () -> { 264 pw.setLocation(w.getLocationOnScreen()); 265 pw.translate(w.getWidth()/2, w.getHeight()/2); 266 if(!c.isVisible()) { 267 Rectangle screenRect = w.getGraphicsConfiguration().getBounds(); 268 pc.setLocation(screenRect.x+screenRect.width/2, 269 screenRect.y+screenRect.height/2); 270 }else{ 271 pc.setLocation(c.getLocationOnScreen()); 272 pc.translate(c.getWidth()/2, c.getHeight()/2); 273 } 274 }); 275 } catch(InterruptedException ie) { 276 throw new RuntimeException("Interrupted"); 277 } catch(java.lang.reflect.InvocationTargetException ite) { 278 ite.printStackTrace(); 279 throw new RuntimeException("InvocationTarget?"); 280 } 281 robot.waitForIdle(delay); 282 // Compare with 1 tolerance to forgive possible rounding errors 283 if(pc.x - pw.x > 1 || 284 pc.x - pw.x < -1 || 285 pc.y - pw.y > 1 || 286 pc.y - pw.y < -1 ) { 287 System.out.println("Center of "+(c.isVisible() ? "Component:" : "screen:")+pc); 288 System.out.println("Center of Window:"+pw); 289 System.out.println("Centers of "+w+" and "+c+" do not coincide"); 290 return false; 291 } 292 return true; 293 } 294 }