1/*
2 * Copyright (c) 2007, 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       6496958
28  @summary   Tests that breaking the proccess of clearing LW requests doesn't break focus.
29  @author    anton.tarasov@...: area=awt-focus
30  @library    ../../regtesthelpers
31  @build      Util
32  @run       main ClearLwQueueBreakTest
33*/
34
35import java.awt.*;
36import javax.swing.*;
37import java.awt.event.*;
38import java.applet.Applet;
39import test.java.awt.regtesthelpers.Util;
40import java.util.concurrent.atomic.AtomicBoolean;
41
42public class ClearLwQueueBreakTest extends Applet {
43    JFrame f1 = new JFrame("frame");
44    JFrame f2 = new JFrame("frame");
45    JButton b = new JButton("button");
46    JTextField tf1 = new JTextField("     ");
47    JTextField tf2 = new JTextField("     ");
48    JTextField tf3 = new JTextField("     ");
49    AtomicBoolean typed = new AtomicBoolean(false);
50    FocusListener listener1;
51    FocusListener listener2;
52
53    Robot robot;
54
55    public static void main(String[] args) {
56        ClearLwQueueBreakTest app = new ClearLwQueueBreakTest();
57        app.init();
58        app.start();
59    }
60
61    public void init() {
62        robot = Util.createRobot();
63
64        // Create instructions for the user here, as well as set up
65        // the environment -- set the layout manager, add buttons,
66        // etc.
67        this.setLayout (new BorderLayout ());
68        Sysout.createDialogWithInstructions(new String[]
69            {"This is an automatic test. Simply wait until it is done."
70            });
71    }
72
73    public void start() {
74        b.addActionListener(new ActionListener() {
75                public void actionPerformed(ActionEvent e) {
76                    f2.setVisible(true);
77                }
78            });
79        tf2.addKeyListener(new KeyAdapter() {
80                public void keyTyped(KeyEvent e) {
81                    if (e.getKeyChar() == '9') {
82                        synchronized (typed) {
83                            typed.set(true);
84                            typed.notifyAll();
85                        }
86                    }
87                }
88            });
89        tf3.addKeyListener(new KeyAdapter() {
90                public void keyTyped(KeyEvent e) {
91                    if (e.getKeyChar() == '8') {
92                        synchronized (typed) {
93                            typed.set(true);
94                            typed.notifyAll();
95                        }
96                    }
97                }
98            });
99
100        listener1 = new FocusAdapter() {
101                public void focusGained(FocusEvent e) {
102                    b.requestFocus();
103                    tf1.requestFocus();
104                    tf1.setFocusable(false);
105                    tf2.requestFocus();
106                }
107            };
108
109        listener2 = new FocusAdapter() {
110                public void focusGained(FocusEvent e) {
111                    b.requestFocus();
112                    tf1.requestFocus();
113                    tf2.requestFocus();
114                    tf2.setFocusable(false);
115                }
116            };
117
118        f1.add(b);
119        f1.add(tf1);
120        f1.add(tf2);
121        f1.add(tf3);
122        f1.setLayout(new FlowLayout());
123        f1.pack();
124        f1.setVisible(true);
125        Util.waitForIdle(robot);
126
127        /*
128         * Break the sequence of LW requests in the middle.
129         * Test that the last request succeeds
130         */
131        f2.addFocusListener(listener1);
132        Sysout.println("Stage 1.");
133        test1();
134
135
136        /*
137         * Break the last LW request.
138         * Test that focus is restored correctly.
139         */
140        f2.removeFocusListener(listener1);
141        f2.addFocusListener(listener2);
142        Sysout.println("Stage 2.");
143        test2();
144
145        Sysout.println("Test passed.");
146    }
147
148    void test1() {
149        Util.clickOnComp(b, robot);
150        Util.waitForIdle(robot);
151
152        if (!tf2.hasFocus()) {
153            throw new TestFailedException("target component didn't get focus!");
154        }
155
156        robot.keyPress(KeyEvent.VK_9);
157        robot.delay(50);
158        robot.keyRelease(KeyEvent.VK_9);
159
160        synchronized (typed) {
161            if (!Util.waitForCondition(typed, 2000)) {
162                throw new TestFailedException("key char couldn't be typed!");
163            }
164        }
165
166        Util.clickOnComp(tf3, robot);
167        Util.waitForIdle(robot);
168
169        if (!tf3.hasFocus()) {
170            throw new Error("a text field couldn't be focused.");
171        }
172
173        typed.set(false);
174        robot.keyPress(KeyEvent.VK_8);
175        robot.delay(50);
176        robot.keyRelease(KeyEvent.VK_8);
177
178        synchronized (typed) {
179            if (!Util.waitForCondition(typed, 2000)) {
180                throw new TestFailedException("key char couldn't be typed!");
181            }
182        }
183    }
184
185    void test2() {
186        Util.clickOnComp(b, robot);
187        Util.waitForIdle(robot);
188
189        if (!b.hasFocus()) {
190            throw new TestFailedException("focus wasn't restored correctly!");
191        }
192    }
193}
194
195class TestFailedException extends RuntimeException {
196    TestFailedException(String msg) {
197        super("Test failed: " + msg);
198    }
199}
200
201/****************************************************
202 Standard Test Machinery
203 DO NOT modify anything below -- it's a standard
204  chunk of code whose purpose is to make user
205  interaction uniform, and thereby make it simpler
206  to read and understand someone else's test.
207 ****************************************************/
208
209/**
210 This is part of the standard test machinery.
211 It creates a dialog (with the instructions), and is the interface
212  for sending text messages to the user.
213 To print the instructions, send an array of strings to Sysout.createDialog
214  WithInstructions method.  Put one line of instructions per array entry.
215 To display a message for the tester to see, simply call Sysout.println
216  with the string to be displayed.
217 This mimics System.out.println but works within the test harness as well
218  as standalone.
219 */
220
221class Sysout
222{
223    static TestDialog dialog;
224
225    public static void createDialogWithInstructions( String[] instructions )
226    {
227        dialog = new TestDialog( new Frame(), "Instructions" );
228        dialog.printInstructions( instructions );
229//        dialog.setVisible(true);
230        println( "Any messages for the tester will display here." );
231    }
232
233    public static void createDialog( )
234    {
235        dialog = new TestDialog( new Frame(), "Instructions" );
236        String[] defInstr = { "Instructions will appear here. ", "" } ;
237        dialog.printInstructions( defInstr );
238//        dialog.setVisible(true);
239        println( "Any messages for the tester will display here." );
240    }
241
242
243    public static void printInstructions( String[] instructions )
244    {
245        dialog.printInstructions( instructions );
246    }
247
248
249    public static void println( String messageIn )
250    {
251        dialog.displayMessage( messageIn );
252    }
253
254}// Sysout  class
255
256/**
257  This is part of the standard test machinery.  It provides a place for the
258   test instructions to be displayed, and a place for interactive messages
259   to the user to be displayed.
260  To have the test instructions displayed, see Sysout.
261  To have a message to the user be displayed, see Sysout.
262  Do not call anything in this dialog directly.
263  */
264class TestDialog extends Dialog
265{
266
267    TextArea instructionsText;
268    TextArea messageText;
269    int maxStringLength = 80;
270
271    //DO NOT call this directly, go through Sysout
272    public TestDialog( Frame frame, String name )
273    {
274        super( frame, name );
275        int scrollBoth = TextArea.SCROLLBARS_BOTH;
276        instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth );
277        add( "North", instructionsText );
278
279        messageText = new TextArea( "", 5, maxStringLength, scrollBoth );
280        add("Center", messageText);
281
282        pack();
283
284//        setVisible(true);
285    }// TestDialog()
286
287    //DO NOT call this directly, go through Sysout
288    public void printInstructions( String[] instructions )
289    {
290        //Clear out any current instructions
291        instructionsText.setText( "" );
292
293        //Go down array of instruction strings
294
295        String printStr, remainingStr;
296        for( int i=0; i < instructions.length; i++ )
297        {
298            //chop up each into pieces maxSringLength long
299            remainingStr = instructions[ i ];
300            while( remainingStr.length() > 0 )
301            {
302                //if longer than max then chop off first max chars to print
303                if( remainingStr.length() >= maxStringLength )
304                {
305                    //Try to chop on a word boundary
306                    int posOfSpace = remainingStr.
307                        lastIndexOf( ' ', maxStringLength - 1 );
308
309                    if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1;
310
311                    printStr = remainingStr.substring( 0, posOfSpace + 1 );
312                    remainingStr = remainingStr.substring( posOfSpace + 1 );
313                }
314                //else just print
315                else
316                {
317                    printStr = remainingStr;
318                    remainingStr = "";
319                }
320
321                instructionsText.append( printStr + "\n" );
322
323            }// while
324
325        }// for
326
327    }//printInstructions()
328
329    //DO NOT call this directly, go through Sysout
330    public void displayMessage( String messageIn )
331    {
332        messageText.append( messageIn + "\n" );
333        System.out.println(messageIn);
334    }
335
336}// TestDialog  class
337