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