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