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