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;// NB: change this to true to test everything 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 91 public static void main(String args[]) { 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 107 // In regular testing, we select just few components to test 108 // randomly. If full testing required, select many ("all"). 109 void selectObjectsToTest(boolean doSwing) { 110 allToplevels.clear(); 111 allComponents.clear(); 112 if(testEverything) { 113 allToplevels.addAll(0, awtToplevels); 114 allComponents.addAll(0, awtComponents); 115 if(doSwing) { 116 allToplevels.addAll(allToplevels.size(), swingToplevels); 117 allComponents.addAll(allComponents.size(), swingComponents); 118 } 119 }else{ 120 //select a random of each 121 int i = (int)(java.lang.Math.random()*awtToplevels.size()); 122 allToplevels.add(awtToplevels.get(i)); 123 i = (int)(java.lang.Math.random()*awtComponents.size()); 124 allComponents.add(awtComponents.get(i)); 125 if(doSwing) { 126 i = (int)(java.lang.Math.random()*swingToplevels.size()); 127 allToplevels.add(swingToplevels.get(i)); 128 i = (int)(java.lang.Math.random()*swingComponents.size()); 129 allComponents.add(swingComponents.get(i)); 130 } 131 } 132 } 133 134 // create Frame, add an AWT component to it, 135 // hide it (or not) and position a new toplevel 136 // relativeTo 137 void doAWTTest(boolean isHidden) { 138 boolean res; 139 ExtendedRobot robot; 140 try { 141 robot = new ExtendedRobot(); 142 }catch(Exception ex) { 143 ex.printStackTrace(); 144 throw new RuntimeException("Failed: "+ex.getMessage()); 145 } 146 Frame container = new Frame("Frame"); 147 container.setBounds(100,100,300,300); 148 container.setLayout(new GridLayout(3,1)); 149 container.add(placeholder); 150 container.setVisible(true); 151 selectObjectsToTest(false); 152 for(Component c: allComponents) { 153 placeholder.setText((isHidden ? "Hidden: " : "Below is ")+ c.getClass().getName()); 154 c.setVisible(true); 155 container.add(c); 156 container.doLayout(); 157 if(isHidden) { 158 c.setVisible(false); 159 } 160 robot.waitForIdle(delay); 161 for(Window w: allToplevels) { 162 w.setLocationRelativeTo(c); 163 w.setVisible(true); 164 robot.waitForIdle(delay); 165 res = compareLocations(w, c, robot); 166 System.out.println(c.getClass().getName()+" \t: "+w.getClass().getName()+ 167 ((w instanceof Frame) && (((Frame)w).isUndecorated()) ? " undec\t\t:" : "\t\t:")+" "+ 168 (res ? "" : "Failed")); 169 if(!res) { 170 throw new RuntimeException("Test failed."); 171 } 172 w.dispose(); 173 } 174 container.remove(c); 175 robot.waitForIdle(delay); 176 } 177 container.dispose(); 178 } 179 180 // Create JFrame, add an AWT or Swing component to it, 181 // hide it (or not) and position a new toplevel 182 // relativeTo 183 void doSwingTest(boolean isHidden) throws InterruptedException, 184 java.lang.reflect.InvocationTargetException { 185 boolean res; 186 ExtendedRobot robot; 187 try { 188 robot = new ExtendedRobot(); 189 }catch(Exception ex) { 190 ex.printStackTrace(); 191 throw new RuntimeException("Failed: "+ex.getMessage()); 192 } 193 194 EventQueue.invokeAndWait( () -> { 195 JFrame jframe = new JFrame("jframe"); 196 jframe.setSize(200,100); 197 swingToplevels.add(jframe); 198 JFrame ujframe = new JFrame("ujframe"); 199 ujframe.setSize(200,100); 200 ujframe.setUndecorated(true); 201 swingToplevels.add(ujframe); 202 JWindow jwin = new JWindow(); 203 jwin.setSize(200,100); 204 swingToplevels.add(jwin); 205 JDialog jdia = new JDialog((Frame)null, "JDialog"); 206 jdia.setSize(200,100); 207 swingToplevels.add(jdia); 208 jcontainer = new JFrame("JFrame"); 209 jcontainer.setBounds(100,100,300,300); 210 jcontainer.setLayout(new GridLayout(3,1)); 211 jcontainer.add(jplaceholder); 212 jcontainer.setVisible(true); 213 selectObjectsToTest(true); 214 }); 215 robot.waitForIdle(delay); 216 217 for(Component c: allComponents) { 218 EventQueue.invokeAndWait( () -> { 219 jplaceholder.setText((isHidden ? "Hidden: " : "Below is: ")+ c.getClass().getName()); 220 c.setVisible(true); 221 jcontainer.add(c); 222 jcontainer.doLayout(); 223 if(isHidden) { 224 c.setVisible(false); 225 } 226 }); 227 robot.waitForIdle(delay); 228 for(Window w: allToplevels) { 229 EventQueue.invokeAndWait( () -> { 230 w.setLocationRelativeTo(c); 231 w.setVisible(true); 232 }); 233 robot.waitForIdle(delay); 234 res = compareLocations(w, c, robot); 235 System.out.println(c.getClass().getName()+" \t: "+w.getClass().getName()+ 236 ((w instanceof Frame) && (((Frame)w).isUndecorated()) ? " undec\t\t:" : "\t\t:")+" "+ 237 (res ? "" : "Failed")); 238 EventQueue.invokeAndWait( () -> { 239 w.dispose(); 240 }); 241 robot.waitForIdle(); 242 if(!res) { 243 throw new RuntimeException("Test failed."); 244 } 245 } 246 EventQueue.invokeAndWait( () -> { 247 jcontainer.remove(c); 248 }); 249 robot.waitForIdle(delay); 250 } 251 EventQueue.invokeAndWait( () -> { 252 jcontainer.dispose(); 253 }); 254 } 255 256 // Check, finally, if w either is concentric with c 257 // or sits in the center of the screen (if c is hidden) 258 boolean compareLocations(final Window w, final Component c, ExtendedRobot robot) { 259 final Point pc = new Point(); 260 final Point pw = new Point(); 261 try { 262 EventQueue.invokeAndWait( () -> { 263 pw.setLocation(w.getLocationOnScreen()); 264 pw.translate(w.getWidth()/2, w.getHeight()/2); 265 if(!c.isVisible()) { 266 Rectangle screenRect = w.getGraphicsConfiguration().getBounds(); 267 pc.setLocation(screenRect.x+screenRect.width/2, 268 screenRect.y+screenRect.height/2); 269 }else{ 270 pc.setLocation(c.getLocationOnScreen()); 271 pc.translate(c.getWidth()/2, c.getHeight()/2); 272 } 273 }); 274 } catch(InterruptedException ie) { 275 throw new RuntimeException("Interrupted"); 276 } catch(java.lang.reflect.InvocationTargetException ite) { 277 ite.printStackTrace(); 278 throw new RuntimeException("InvocationTarget?"); 279 } 280 robot.waitForIdle(delay); 281 // Compare with 1 tolerance to forgive possible rounding errors 282 if(pc.x - pw.x > 1 || 283 pc.x - pw.x < -1 || 284 pc.y - pw.y > 1 || 285 pc.y - pw.y < -1 ) { 286 System.out.println("Center of "+(c.isVisible() ? "Component:" : "screen:")+pc); 287 System.out.println("Center of Window:"+pw); 288 System.out.println("Centers of "+w+" and "+c+" do not coincide"); 289 return false; 290 } 291 return true; 292 } 293 }