1 /* 2 * Copyright (c) 2003, 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 @test 25 @bug 4799136 26 @summary Tests that type-ahead for dialog works and doesn't block program 27 @author Dmitry.Cherepanov@SUN.COM area=awt.focus 28 @run main FreezeTest 29 */ 30 31 import java.awt.*; 32 import java.lang.reflect.InvocationTargetException; 33 import java.awt.event.*; 34 import java.util.concurrent.CountDownLatch; 35 import java.util.concurrent.TimeUnit; 36 37 /* 38 * Tests that type-ahead doesn't block program. 39 */ 40 41 public class FreezeTest 42 { 43 static Frame f; 44 static Button b; 45 static Dialog d; 46 static TextField tf; 47 static CountDownLatch robotLatch = new CountDownLatch(1); 48 static Robot robot; 49 static int click_count = 100; 50 static int deliver_count = 0; 51 52 public static void main(String args[]) throws Exception { 53 FreezeTest test = new FreezeTest(); 54 test.init(); 55 test.start(); 56 } 57 public void init() 58 { 59 Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { 60 public void eventDispatched(AWTEvent e) { 61 if (e instanceof KeyEvent){ 62 deliver_count++; 63 System.err.println("key_event# "+deliver_count); 64 } 65 66 if (e instanceof InputEvent){ 67 System.err.println(e.toString()+","+((InputEvent)e).getWhen()); 68 }else{ 69 System.err.println(e.toString()); 70 } 71 } 72 }, AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK); 73 74 75 f = new Frame("frame"); 76 b = new Button("press"); 77 d = new Dialog(f, "dialog", true); 78 tf = new TextField(""); 79 d.add(tf); 80 d.pack(); 81 82 f.add(b); 83 f.pack(); 84 b.addActionListener(new ActionListener() { 85 public void actionPerformed(ActionEvent e) { 86 System.err.println(e.toString()+","+e.getWhen()); 87 System.err.println("B pressed"); 88 robotLatch.countDown(); 89 90 EventQueue.invokeLater(new Runnable() { 91 public void run() { 92 waitTillShown(d); 93 FreezeTest.this.d.toFront(); 94 FreezeTest.this.moveMouseOver(d); 95 } 96 }); 97 d.setVisible(true); 98 } 99 }); 100 101 }//End init() 102 103 public void start () throws Exception 104 { 105 robot = new Robot(); 106 107 f.setVisible(true); 108 waitTillShown(b); 109 System.err.println("b is shown"); 110 f.toFront(); 111 moveMouseOver(f); 112 robot.waitForIdle(); 113 makeFocused(b); 114 robot.waitForIdle(); 115 System.err.println("b is focused"); 116 117 robot.keyPress(KeyEvent.VK_SPACE); 118 robot.keyRelease(KeyEvent.VK_SPACE); 119 boolean ok = robotLatch.await(1, TimeUnit.SECONDS); 120 if(!ok) { 121 throw new RuntimeException("Was B button pressed?"); 122 } 123 124 for (int i = 0; i < click_count; i++){ 125 System.err.println("click# "+(i+1)); 126 robot.keyPress(KeyEvent.VK_SPACE); 127 robot.delay(10); 128 robot.keyRelease(KeyEvent.VK_SPACE); 129 robot.delay(50); 130 } 131 132 robot.waitForIdle(); 133 134 int deliver_count = this.deliver_count; 135 int expected_count = (click_count + 1) * 3; 136 137 if (deliver_count != expected_count){ 138 System.err.println("deliver_count = "+deliver_count+" (!="+expected_count+")"); 139 throw new RuntimeException("incorrect behaviour"); 140 } 141 }// start() 142 143 private void moveMouseOver(Container c) { 144 Point p = c.getLocationOnScreen(); 145 Dimension d = c.getSize(); 146 robot.mouseMove(p.x + (int)(d.getWidth()/2), p.y + (int)(d.getHeight()/2)); 147 } 148 149 private void waitTillShown(Component c) { 150 while (true) { 151 try { 152 Thread.sleep(100); 153 c.getLocationOnScreen(); 154 break; 155 } catch (InterruptedException ie) { 156 ie.printStackTrace(); 157 break; 158 } catch (Exception e) { 159 } 160 } 161 } 162 private void makeFocused(Component comp) { 163 if (comp.isFocusOwner()) { 164 return; 165 } 166 final Semaphore sema = new Semaphore(); 167 final FocusAdapter fa = new FocusAdapter() { 168 public void focusGained(FocusEvent fe) { 169 sema.raise(); 170 } 171 }; 172 comp.addFocusListener(fa); 173 comp.requestFocusInWindow(); 174 if (comp.isFocusOwner()) { 175 return; 176 } 177 try { 178 sema.doWait(3000); 179 } catch (InterruptedException ie) { 180 ie.printStackTrace(); 181 } 182 comp.removeFocusListener(fa); 183 if (!comp.isFocusOwner()) { 184 throw new RuntimeException("Can't make " + comp + " focused, current owner is " + KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner()); 185 } 186 } 187 188 static class Semaphore { 189 boolean state = false; 190 int waiting = 0; 191 public Semaphore() { 192 } 193 public synchronized void doWait() throws InterruptedException { 194 if (state) { 195 return; 196 } 197 waiting++; 198 wait(); 199 waiting--; 200 } 201 public synchronized void doWait(int timeout) throws InterruptedException { 202 if (state) { 203 return; 204 } 205 waiting++; 206 wait(timeout); 207 waiting--; 208 } 209 public synchronized void raise() { 210 state = true; 211 if (waiting > 0) { 212 notifyAll(); 213 } 214 } 215 public synchronized boolean getState() { 216 return state; 217 } 218 } 219 }