1 /* 2 * Copyright (c) 2008, 2016, 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 @key headful 27 @bug 4452384 28 @summary Tests that non-focusable windows doesn't generate any focus events when accessed. 29 @author Denis.Mikhalkin: area=awt.focus 30 @run main NoEventsTest 31 */ 32 33 import java.awt.*; 34 import java.awt.event.*; 35 import java.util.*; 36 37 public class NoEventsTest extends Frame { 38 public static final int DEF_WIDTH = 400, 39 DEF_HEIGHT = 300, 40 DEF_TOP = 1, 41 DEF_LEFT = 100, 42 DEF_ROW = 0, 43 DEF_COL = 0; 44 static boolean automatic = true; 45 static Window[] windows; 46 static Frame main_frame, jumpingFrame; 47 static Button focus_button; 48 static Robot robot; 49 static void pause(int timeout) { 50 Toolkit.getDefaultToolkit().sync(); 51 robot.waitForIdle(); 52 robot.delay(100); 53 } 54 static GlobalListener listener; 55 public static void main(String[] args) { 56 57 listener = new GlobalListener(); 58 Toolkit.getDefaultToolkit().addAWTEventListener(listener, 59 AWTEvent.FOCUS_EVENT_MASK | 60 AWTEvent.WINDOW_EVENT_MASK); 61 try{ 62 robot = new Robot(); 63 } catch(Exception e) {} 64 // Create several pairs - focusable Frame with focusable component(button) and non-focusable: 65 // window, resizable frame, non-resizable frame, dialog, non-resiable dialog 66 main_frame = new Frame("focusable frame"); 67 focus_button = new Button("button to focus"); 68 main_frame.add(focus_button); 69 main_frame.pack(); 70 main_frame.setVisible(true); 71 main_frame.setLocation(10, 600); 72 main_frame.addWindowListener(new WindowAdapter() { 73 public void windowClosing(WindowEvent e) { 74 listener.report(); 75 System.exit(0); 76 } 77 }); 78 79 jumpingFrame = new Frame("Jumping frame"); 80 jumpingFrame.setBounds(DEF_LEFT, DEF_TOP, DEF_WIDTH, DEF_HEIGHT); 81 82 windows = new Window[7]; 83 windows[0] = new TestWindow(0, 0, false, main_frame); 84 //windows[1] = new TestWindow(2, 1, true, main_frame); 85 windows[2] = new NoEventsTest(1, 0, false, true); 86 windows[3] = new NoEventsTest(2, 0, false, false); 87 //windows[4] = new Test(3, 0, true, true); 88 windows[5] = new TestDialog(0, 1, false, true, main_frame); 89 windows[6] = new TestDialog(1, 1, false, false, main_frame); 90 if (!automatic) { 91 int windowInd; 92 for (windowInd = 0; windowInd < windows.length; windowInd++) { 93 if (windows[windowInd] != null) { 94 windows[windowInd].setVisible(true); 95 } 96 } 97 } 98 // Run the test 99 // 1. Click on all controls, check for no focus events for non-focusable, right focus events for focusable 100 // 2. Perform some action with control, check if it works 101 if (automatic) { 102 int windowInd; 103 for (windowInd = 0; windowInd < windows.length; windowInd++) { 104 if (windows[windowInd] != null) { 105 windows[windowInd].setVisible(true); 106 focus_button.requestFocus(); 107 pause(1000); 108 109 // Verify that click on non-focusable window causes no focus lost on active window 110 performFocusClick(windows[windowInd]); 111 focus_button.requestFocus(); 112 pause(500); 113 performActionClick(windows[windowInd]); 114 115 // Verify that toFront, toBack doesn't cause non-focusable window to become active 116 jumpingFrame.setVisible(true); 117 pause(1000); 118 jumpingFrame.toBack(); 119 pause(500); 120 jumpingFrame.toFront(); 121 pause(500); 122 windows[windowInd].toBack(); 123 pause(500); 124 windows[windowInd].toFront(); 125 pause(500); 126 127 // Verify that iconifiyng/deiconfiying and 128 // zooming/unzooming doesn't cause non-focusable 129 // window to become active 130 if (windows[windowInd] instanceof Frame) { 131 Frame toTest = (Frame)windows[windowInd]; 132 // Deiconification currently doesn't work! 133 // toTest.setExtendedState(Frame.ICONIFIED); 134 // pause(500); 135 // toTest.setExtendedState(Frame.NORMAL); 136 pause(500); 137 toTest.setExtendedState(Frame.MAXIMIZED_BOTH); 138 pause(500); 139 toTest.setExtendedState(Frame.NORMAL); 140 } 141 142 windows[windowInd].dispose(); 143 jumpingFrame.dispose(); 144 } 145 } 146 pause(1000); 147 System.err.println("Test finished."); 148 if (!listener.report()) { 149 throw new RuntimeException("Test Failed. See error stream output for details"); 150 } 151 } 152 } 153 static void performFocusClick(Window parent) { 154 if (parent == null) { 155 return; 156 } 157 for (int compInd = 0; compInd < parent.getComponentCount(); compInd++) { 158 Component child = parent.getComponent(compInd); 159 if (child instanceof TestPanel) { 160 TestPanel pan = (TestPanel)child; 161 pan.performFocusClicks(robot); 162 pause(100); 163 } 164 } 165 } 166 static void performActionClick(Window parent) { 167 if (parent == null) { 168 return; 169 } 170 for (int compInd = 0; compInd < parent.getComponentCount(); compInd++) { 171 Component child = parent.getComponent(compInd); 172 if (child instanceof TestPanel) { 173 TestPanel pan = (TestPanel)child; 174 pan.performActionClicks(robot); 175 pause(100); 176 } 177 } 178 } 179 public NoEventsTest(int row, int col, boolean focusable, boolean resizable) { 180 super("Frame" + row + "" + col); 181 TestPanel panel = new TestPanel(row, col); 182 if (NoEventsTest.automatic) { 183 row = NoEventsTest.DEF_ROW; 184 col = NoEventsTest.DEF_COL; 185 } 186 setName(getTitle()); 187 add("Center", panel); 188 Label l = new Label(getClass().getSuperclass().getName() + ", " + (focusable?"focusable":"non-focusable") + 189 ", " + (resizable?"resizable":"non-resizable")); 190 l.setBackground(Color.green); 191 add("North", l); 192 setBounds(NoEventsTest.DEF_LEFT + DEF_WIDTH*col, DEF_TOP + DEF_HEIGHT*row, DEF_WIDTH, DEF_HEIGHT); 193 if (!focusable) { 194 setFocusableWindowState(false); 195 } 196 if (!resizable) { 197 setResizable(false); 198 } 199 // setVisible(true); 200 } 201 } 202 class TestWindow extends Window { 203 public TestWindow(int row, int col, boolean focusable, Frame owner) { 204 super(owner); 205 setName("Window" + row + "" + col); 206 TestPanel panel = new TestPanel(row, col); 207 if (NoEventsTest.automatic) { 208 row = NoEventsTest.DEF_ROW; 209 col = NoEventsTest.DEF_COL; 210 } 211 212 add("Center", panel); 213 Label l = new Label(getClass().getSuperclass().getName() + ", " + (focusable?"focusable":"non-focusable") + 214 ", " + (false?"resizable":"non-resizable")); 215 l.setBackground(Color.green); 216 add("North", l); 217 218 setBounds(NoEventsTest.DEF_LEFT + NoEventsTest.DEF_WIDTH*col, NoEventsTest.DEF_TOP + NoEventsTest.DEF_HEIGHT*row, NoEventsTest.DEF_WIDTH, NoEventsTest.DEF_HEIGHT); 219 if (!focusable) { 220 setFocusableWindowState(false); 221 } 222 // setVisible(true); 223 } 224 } 225 class TestDialog extends Dialog { 226 public TestDialog(int row, int col, boolean focusable, boolean resizable, Frame owner) { 227 super(owner); 228 setName("Dialog" + row + "" + col); 229 TestPanel panel = new TestPanel(row, col); 230 if (NoEventsTest.automatic) { 231 row = NoEventsTest.DEF_ROW; 232 col = NoEventsTest.DEF_COL; 233 } 234 235 add("Center", panel); 236 Label l = new Label(getClass().getSuperclass().getName() + ", " + (focusable?"focusable":"non-focusable") + 237 ", " + (resizable?"resizable":"non-resizable")); 238 l.setBackground(Color.green); 239 add("North", l); 240 241 setBounds(NoEventsTest.DEF_LEFT + NoEventsTest.DEF_WIDTH*col, NoEventsTest.DEF_TOP + NoEventsTest.DEF_HEIGHT*row, NoEventsTest.DEF_WIDTH, NoEventsTest.DEF_HEIGHT); 242 if (!focusable) { 243 setFocusableWindowState(false); 244 } 245 if (!resizable) { 246 setResizable(false); 247 } 248 // setVisible(true); 249 } 250 } 251 252 class TestPanel extends Panel { 253 254 void clickComponent(Component comp, Robot robot) { 255 if (comp instanceof Choice) { 256 return; 257 } 258 Point compLoc = comp.getLocationOnScreen(); 259 Dimension size = comp.getSize(); 260 robot.mouseMove(compLoc.x + size.width/2, compLoc.y + size.height/2); 261 robot.mousePress(InputEvent.BUTTON1_MASK); 262 robot.mouseRelease(InputEvent.BUTTON1_MASK); 263 } 264 void performFocusClicks(Robot robot) { 265 for (int childInd = 0; childInd < getComponentCount(); childInd++) { 266 performFocusClick(getComponent(childInd), robot); 267 } 268 } 269 void performFocusClick(Component comp, Robot robot) { 270 clickComponent(comp, robot); 271 } 272 273 void performActionClicks(Robot robot) { 274 for (int childInd = 0; childInd < getComponentCount(); childInd++) { 275 performActionClick(getComponent(childInd), robot); 276 } 277 } 278 void performActionClick(Component comp, Robot robot) { 279 } 280 281 public TestPanel(int row, int col) { 282 setLayout(new FlowLayout()); 283 Button b; 284 add(b = new Button("press"+ row + "" + col)); 285 b.setName(b.getLabel()); 286 // b.addMouseListener(new MouseAdapter() { 287 // public void mousePressed(MouseEvent e) { 288 // System.err.println(e); 289 // } 290 // }); 291 TextField t; 292 add(t = new TextField("text" + row + "" + col)); 293 t.setName(t.getText()); 294 295 java.awt.List list = new java.awt.List(); 296 add(list); 297 list.setName("list"); 298 list.add("one"); 299 list.add("two"); 300 list.add("three"); 301 list.setMultipleMode(true); 302 list.setName("list" + row + "" + col); 303 304 Checkbox check = new Checkbox("checker"); 305 add(check); 306 check.setName("check" + row + "" + col); 307 308 Choice choice = new Choice(); 309 choice.add("one"); 310 choice.add("two"); 311 choice.add("three"); 312 add(choice); 313 choice.setName("choice" + row + "" + col); 314 315 Canvas can = new Canvas() { 316 public Dimension getPreferredSize() { 317 return new Dimension(10, 10); 318 } 319 }; 320 can.setBackground(Color.blue); 321 add(can); 322 can.setName("canvas" + row + "" + col); 323 324 TextArea ta = new TextArea("text\ntttt\naaaa\nwwwww\nqqqqqq\neeeeee\nrrrrrr\nyyyyyy\nuuuuu", 3, 5); 325 add(ta); 326 ta.setName("textarea" + row + "" + col); 327 328 Scrollbar bar = new Scrollbar(Scrollbar.HORIZONTAL); 329 add(bar); 330 bar.setName("scrollbar" + row + "" + col); 331 332 CheckboxGroup group = new CheckboxGroup(); 333 Checkbox ch1 = new Checkbox("one", group, true); 334 Checkbox ch2 = new Checkbox("two", group, false); 335 add(ch1); 336 add(ch2); 337 ch1.setName("checkbox1 " + row + "" + col); 338 ch2.setName("checkbox2 " + row + "" + col); 339 340 341 ScrollPane pane = new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS); 342 add(pane); 343 Button bigButton = new Button("abc") { 344 public Dimension getPreferredSize() { 345 return new Dimension(100, 100); 346 } 347 }; 348 pane.add(bigButton); 349 bigButton.setName("bigbutton" + row + "" + col); 350 } 351 } 352 353 class GlobalListener implements AWTEventListener { 354 java.util.List errors = new java.util.LinkedList(); 355 public boolean report() { 356 if (errors.size() != 0) { 357 System.err.println("Test FAILED"); 358 } else { 359 System.err.println("Test PASSED"); 360 return true; 361 } 362 ListIterator iter = errors.listIterator(); 363 while (iter.hasNext()) { 364 System.err.println(iter.next()); 365 } 366 return false; 367 } 368 public GlobalListener() { 369 } 370 Window getWindowParent(Component comp) { 371 while (comp != null && !(comp instanceof Window)) { 372 comp = comp.getParent(); 373 } 374 return (Window)comp; 375 } 376 void reportError(AWTEvent e, String message) { 377 String error = "ERROR: " + message + " : " + e; 378 errors.add(error); 379 System.err.println(error); 380 } 381 public void eventDispatched(AWTEvent e) { 382 Component comp = (Component)e.getSource(); 383 Window parent = getWindowParent(comp); 384 if (!(e instanceof WindowEvent || e instanceof FocusEvent)) { 385 System.err.println("Strange event " + e); 386 } 387 388 // Skip WINDOW_OPENED 389 if (e.getID() == WindowEvent.WINDOW_CLOSING) { 390 System.err.println(e); 391 } 392 switch (e.getID()) { 393 case WindowEvent.WINDOW_OPENED: 394 case WindowEvent.WINDOW_CLOSING: 395 case WindowEvent.WINDOW_CLOSED: 396 case WindowEvent.WINDOW_ICONIFIED: 397 case WindowEvent.WINDOW_DEICONIFIED: 398 case WindowEvent.WINDOW_STATE_CHANGED: 399 return; 400 case WindowEvent.WINDOW_LOST_FOCUS: { 401 WindowEvent we = (WindowEvent)e; 402 if (we.getOppositeWindow() != null && !we.getOppositeWindow().getFocusableWindowState()) { 403 reportError(e, "frame lost focus because of non-focusable window"); 404 } 405 break; 406 } 407 } 408 // Check that Window owner is focusable 409 if (!parent.getFocusableWindowState()) { 410 reportError(e, "focus event for component in non-focusable window " + parent.getName()); 411 } 412 if (!comp.isFocusable()) { 413 reportError(e, "focus event for non-focusable component"); 414 } 415 // if (e instanceof WindowEvent || e instanceof FocusEvent) { 416 // // System.err.println(e); 417 // } 418 } 419 }