NestedModelessDialogTest.java revision 17565:b762aafa34e3
118334Speter/*
218334Speter * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
372562Sobrien * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4169689Skan *
5169689Skan * This code is free software; you can redistribute it and/or modify it
618334Speter * under the terms of the GNU General Public License version 2 only, as
790075Sobrien * published by the Free Software Foundation.
818334Speter *
990075Sobrien * This code is distributed in the hope that it will be useful, but WITHOUT
1090075Sobrien * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1190075Sobrien * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1290075Sobrien * version 2 for more details (a copy is included in the LICENSE file that
1318334Speter * accompanied this code).
1490075Sobrien *
1590075Sobrien * You should have received a copy of the GNU General Public License version
1690075Sobrien * 2 along with this work; if not, write to the Free Software Foundation,
1790075Sobrien * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1818334Speter *
1918334Speter * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
2090075Sobrien * or visit www.oracle.com if you need additional information or have any
21169689Skan * questions.
22169689Skan */
2318334Speter
2418334Speter/**
2518334Speter * @test 8155740
2650397Sobrien * @key headful
27132718Skan * @summary See <rdar://problem/3429130>: Events: actionPerformed() method not
28132718Skan *              called when it is button is clicked (system load related)
2952284Sobrien * @summary com.apple.junit.java.awt.Frame
3018334Speter * @library ../../../regtesthelpers
3118334Speter * @build VisibilityValidator
3290075Sobrien * @build Util
3318334Speter * @build Waypoint
3418334Speter * @run main NestedModelessDialogTest -Xlog:exception
3518334Speter */
3690075Sobrien
3718334Speter/////////////////////////////////////////////////////////////////////////////
3818334Speter//  NestedModelessDialogTest.java
39117395Skan// The test launches a parent frame. From this parent frame it launches a modal
4018334Speter// dialog. From the modal dialog it launches a modeless dialog with a text
41132718Skan// field in it and tries to write into the text field. The test succeeds if you
42132718Skan// are successfully able to write into this Nested Modeless Dialog
43132718Skan/////////////////////////////////////////////////////////////////////////////
44132718Skan// classes necessary for this test
45132718Skanimport java.awt.*;
46132718Skanimport java.awt.event.*;
47132718Skanimport java.util.Enumeration;
48132718Skan
49132718Skanimport test.java.awt.regtesthelpers.Util;
50132718Skanimport test.java.awt.regtesthelpers.VisibilityValidator;
51132718Skanimport test.java.awt.regtesthelpers.Waypoint;
52132718Skan
53132718Skanpublic class NestedModelessDialogTest {
54132718Skan
55169689Skan    Waypoint[] event_checkpoint = new Waypoint[3];
56169689Skan    VisibilityValidator[] win_checkpoint = new VisibilityValidator[2];
5718334Speter
58169689Skan    IntermediateDialog interDiag;
59169689Skan    TextDialog txtDiag;
60169689Skan
61117395Skan    // Global variables so the robot thread can locate things.
6296263Sobrien    Button[] robot_button = new Button[2];
6318334Speter    TextField robot_text = null;
6418334Speter    static Robot _robot = null;
6518334Speter
66169689Skan    /**
67169689Skan     * Get called by test harness
6818334Speter     *
6918334Speter     * @throws Exception
7090075Sobrien     */
7118334Speter    public void testModelessDialogs() throws Exception {
7218334Speter        Frame frame = null;
7318334Speter        String result = "";
7418334Speter        Robot robot = getRobot();
7518334Speter
7618334Speter        event_checkpoint[0] = new Waypoint(); // "-Launch 1-"
7718334Speter        event_checkpoint[1] = new Waypoint(); // "-Launch 2-"
7818334Speter
7918334Speter        // launch first frame with fistButton
8018334Speter        frame = new StartFrame();
8190075Sobrien        VisibilityValidator.setVisibleAndConfirm(frame);
8290075Sobrien        Util.clickOnComp(robot_button[0], robot);
8390075Sobrien
8490075Sobrien        // Dialog must be created and onscreen before we proceed.
8590075Sobrien        //   The event_checkpoint waits for the Dialog to be created.
8690075Sobrien        //   The win_checkpoint waits for the Dialog to be visible.
8790075Sobrien        event_checkpoint[0].requireClear();
8890075Sobrien        win_checkpoint[0].requireVisible();
8990075Sobrien        Util.clickOnComp(robot_button[1], robot);
9090075Sobrien
9190075Sobrien        // Again, the Dialog must be created and onscreen before we proceed.
9290075Sobrien        //   The event_checkpoint waits for the Dialog to be created.
9390075Sobrien        //   The win_checkpoint waits for the Dialog to be visible.
9490075Sobrien        event_checkpoint[1].requireClear();
9590075Sobrien        win_checkpoint[1].requireVisible();
9690075Sobrien        Util.clickOnComp(robot_text, robot);
9790075Sobrien
9890075Sobrien        // I'm really not sure whether the click is needed for focus
9990075Sobrien        // but since it's asynchronous, as is the actually gaining of focus
100169689Skan        // we might as well do our best
101169689Skan        try {
102169689Skan            EventQueue.invokeAndWait(new Runnable() {
103169689Skan                public void run() {
104169689Skan                }
105169689Skan            });
10618334Speter        } catch (Exception e) {
107169689Skan        }
108169689Skan
10918334Speter        robot.keyPress(KeyEvent.VK_SHIFT);
11018334Speter
11118334Speter        robot.keyPress(KeyEvent.VK_H);
11218334Speter        robot.waitForIdle();
113132718Skan        robot.keyRelease(KeyEvent.VK_H);
11418334Speter
115169689Skan        robot.keyRelease(KeyEvent.VK_SHIFT);
116169689Skan
117169689Skan        robot.keyPress(KeyEvent.VK_E);
118169689Skan        robot.waitForIdle();
119169689Skan        robot.keyRelease(KeyEvent.VK_E);
120169689Skan
121169689Skan        robot.keyPress(KeyEvent.VK_L);
122169689Skan        robot.waitForIdle();
123169689Skan        robot.keyRelease(KeyEvent.VK_L);
124169689Skan
125169689Skan        robot.keyPress(KeyEvent.VK_L);
126169689Skan        robot.waitForIdle();
127169689Skan        robot.keyRelease(KeyEvent.VK_L);
128169689Skan
129169689Skan        robot.keyPress(KeyEvent.VK_O);
130169689Skan        robot.waitForIdle();
131169689Skan        robot.keyRelease(KeyEvent.VK_O);
132169689Skan
133169689Skan        //
134169689Skan        // NOTE THAT WE MAY HAVE MORE SYNCHRONIZATION WORK TO DO HERE.
135169689Skan        // CURRENTLY THERE IS NO GUARANTEE THAT THE KEYEVENT THAT THAT
136169689Skan        // TYPES THE 'O' HAS BEEN PROCESSED BEFORE WE GET THE RESULT
137169689Skan        //
13818334Speter        // This is a (lame) attempt at waiting for the last typeKey events to
13918334Speter        // propagate. It's not quite right because robot uses
140169689Skan        // CGRemoteOperations, which are asynchronous. But that's why I put in
14118334Speter        // the Thread.sleep
142169689Skan        try {
143169689Skan            EventQueue.invokeAndWait(new Runnable() {
144169689Skan                public void run() {
145169689Skan                }
146169689Skan            });
14718334Speter        } catch (Exception e) {
148169689Skan        }
14918334Speter
150169689Skan        // Need to call this before the dialog that robot_text is in is disposed
151169689Skan        result = robot_text.getText();
152169689Skan
15318334Speter        Thread.sleep(50); // Thread.sleep adds stability
154169689Skan        // Click Close box of modeless dialog with textField
155169689Skan        Util.clickOnComp(txtDiag, robot);
156169689Skan
15718334Speter        Thread.sleep(50); // Thread.sleep adds stability
158169689Skan        // Click Close box of intermediate modal dialog
159169689Skan        Util.clickOnComp(interDiag, robot);
16018334Speter
161169689Skan        Thread.sleep(50); // Thread.sleep adds stability
162169689Skan        // Click Close box of intermediate modal dialog
163169689Skan        Util.clickOnComp(frame, robot);
16418334Speter
165169689Skan        String expected = "Hello";
166169689Skan    }
167169689Skan
16818334Speter    private static Robot getRobot() {
169169689Skan        if (_robot == null) {
170169689Skan            try {
171169689Skan                _robot = new Robot();
17218334Speter            } catch (AWTException e) {
173169689Skan                throw new RuntimeException("Robot creation failed");
174169689Skan            }
175169689Skan        }
17618334Speter        return _robot;
177169689Skan    }
178169689Skan
179169689Skan    //////////////////// Start Frame ///////////////////
18018334Speter    /**
181169689Skan     * Launches the first frame with a button in it
182169689Skan     */
18318334Speter    class StartFrame extends Frame {
184169689Skan
185169689Skan        /**
186169689Skan         * Constructs a new instance.
18718334Speter         */
188169689Skan        public StartFrame() {
189169689Skan            super("First Frame");
19018334Speter            setLayout(new GridBagLayout());
191169689Skan            setLocation(375, 200);
192169689Skan            setSize(271, 161);
193169689Skan            Button but = new Button("Make Intermediate");
194169689Skan            but.addActionListener(new java.awt.event.ActionListener() {
195169689Skan                public void actionPerformed(ActionEvent e) {
196169689Skan                    interDiag = new IntermediateDialog(StartFrame.this);
197169689Skan                    win_checkpoint[0] = new VisibilityValidator(interDiag);
198169689Skan                    interDiag.setSize(300, 200);
199169689Skan
200169689Skan                    // may need listener to watch this move.
201169689Skan                    interDiag.setLocation(getLocationOnScreen());
202169689Skan                    interDiag.pack();
203169689Skan                    event_checkpoint[0].clear();
204169689Skan                    interDiag.setVisible(true);
205169689Skan                }
206169689Skan            });
207169689Skan            Panel pan = new Panel();
20818334Speter            pan.add(but);
20918334Speter            add(pan);
21018334Speter            robot_button[0] = but;
21118334Speter            addWindowListener(new WindowAdapter() {
212169689Skan                public void windowClosing(WindowEvent e) {
213169689Skan                    setVisible(false);
214169689Skan                    dispose();
215169689Skan                }
216169689Skan            });
217169689Skan        }
218169689Skan    }
219169689Skan
220169689Skan    ///////////////////////////// VARIOUS DIALOGS //////////////////////////
221169689Skan    /* A Dialog that launches a sub-dialog */
222169689Skan    class IntermediateDialog extends Dialog {
223169689Skan
224169689Skan        Dialog m_parent;
225169689Skan
226169689Skan        public IntermediateDialog(Frame parent) {
227169689Skan            super(parent, "Intermediate Modal", true /*Modal*/);
228169689Skan            m_parent = this;
229169689Skan            Button but = new Button("Make Text");
230169689Skan            but.addActionListener(new java.awt.event.ActionListener() {
231169689Skan                public void actionPerformed(ActionEvent e) {
232169689Skan                    txtDiag = new TextDialog(m_parent);
233169689Skan                    win_checkpoint[1] = new VisibilityValidator(txtDiag);
234169689Skan                    txtDiag.setSize(300, 100);
235169689Skan                    event_checkpoint[1].clear();
236169689Skan                    txtDiag.setVisible(true);
23718334Speter                }
23818334Speter            });
23918334Speter            Panel pan = new Panel();
240169689Skan            pan.add(but);
241169689Skan            add(pan);
242169689Skan            pack();
243169689Skan            addWindowListener(new WindowAdapter() {
244169689Skan                public void windowClosing(WindowEvent e) {
245169689Skan                    setVisible(false);
246169689Skan                    dispose();
24718334Speter                }
248169689Skan            });
249169689Skan
250169689Skan            // The robot needs to know about us, so set global
251169689Skan            robot_button[1] = but;
252169689Skan        }
253169689Skan    }
254169689Skan
255169689Skan    /* A Dialog that just holds a text field */
256169689Skan    class TextDialog extends Dialog {
257169689Skan
258169689Skan        public TextDialog(Dialog parent) {
259169689Skan            super(parent, "Modeless Dialog", false /*Modeless*/);
260169689Skan            TextField txt = new TextField("", 10);
261169689Skan            Panel pan = new Panel();
26218334Speter            pan.add(txt);
26318334Speter            add(pan);
26418334Speter            pack();
26518334Speter            addWindowListener(new WindowAdapter() {
26618334Speter                public void windowClosing(WindowEvent e) {
26718334Speter                    setVisible(false);
26818334Speter                    dispose();
26918334Speter                }
270132718Skan            });
27118334Speter
27250397Sobrien            // The robot needs to know about us, so set global
27350397Sobrien            robot_text = txt;
27450397Sobrien        }
27550397Sobrien    }
27650397Sobrien
27750397Sobrien    public static void main(String[] args) throws RuntimeException {
27818334Speter        try {
27990075Sobrien            new NestedModelessDialogTest().testModelessDialogs();
28090075Sobrien        } catch (Exception e) {
28190075Sobrien            throw new RuntimeException("NestedModelessDialogTest object "
28290075Sobrien                    + "creation failed");
28390075Sobrien        }
28490075Sobrien    }
285132718Skan}
28690075Sobrien