PreserveDispatchThread.java revision 14851:980da45565c8
1/*
2 * Copyright (c) 2010, 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 6424157
28  @author Artem Ananiev: area=eventqueue
29  @run main PreserveDispatchThread
30*/
31
32import java.awt.*;
33import java.awt.event.*;
34
35public class PreserveDispatchThread {
36
37    private static volatile Frame f;
38    private static volatile Dialog d;
39
40    private static volatile boolean isEDT = true;
41
42    public static void main(String[] args) throws Exception {
43        f = new Frame("F");
44        f.setSize(320, 340);
45        f.setLocationRelativeTo(null);
46        f.setVisible(true);
47
48        try {
49            test1();
50            if (!isEDT) {
51                throw new RuntimeException("Test FAILED (test1): event dispatch thread is changed");
52            }
53
54            test2();
55            if (!isEDT) {
56                throw new RuntimeException("Test FAILED (test2): event dispatch thread is changed");
57            }
58
59            test3();
60            if (!isEDT) {
61                throw new RuntimeException("Test FAILED (test3): event dispatch thread is changed");
62            }
63        } finally {
64            if (d != null) {
65                d.dispose();
66            }
67            f.dispose();
68        }
69    }
70
71    /*
72     * Tests that push/pop doesn't change the dispatch thread if
73     * called on EDT.
74     */
75    private static void test1() throws Exception {
76        EventQueue.invokeAndWait(new Runnable() {
77            @Override
78            public void run() {
79                TestEventQueue teq = new TestEventQueue();
80                EventQueue seq = Toolkit.getDefaultToolkit().getSystemEventQueue();
81                try {
82                    seq.push(teq);
83                    d = new TestDialog();
84                    d.setVisible(true);
85                    checkEDT();
86                } finally {
87                    teq.pop();
88                }
89                checkEDT();
90            }
91        });
92    }
93
94    /*
95     * Tests that push/pop doesn't change the dispatch thread if
96     * called on the main thread.
97     */
98    private static void test2() throws Exception {
99        TestEventQueue teq = new TestEventQueue();
100        EventQueue seq = Toolkit.getDefaultToolkit().getSystemEventQueue();
101        try {
102            seq.push(teq);
103            EventQueue.invokeAndWait(new Runnable() {
104                @Override
105                public void run() {
106                    checkEDT();
107                    d = new TestDialog();
108                    d.setVisible(true);
109                    checkEDT();
110                }
111            });
112        } finally {
113            teq.pop();
114        }
115    }
116
117    private static final Object test3Lock = new Object();
118    private static boolean test3Sync = false;
119
120    /*
121     * A complex test: several nested invokeLater() are called and
122     * in every runnable a check for EDT is performed. At the ent
123     * of the test we wait for all the runnables to be processed
124     * and the dialog is disposed; otherwise the last EDT check can
125     * be later than this method returns and the whole test is passed.
126     */
127    private static void test3() throws Exception {
128        EventQueue.invokeLater(new Runnable() {
129            @Override
130            public void run() {
131                d = new Dialog(f, true);
132                d.setSize(240, 180);
133                d.setLocationRelativeTo(f);
134                EventQueue.invokeLater(new Runnable() {
135                    @Override
136                    public void run() {
137                        d.setVisible(true);
138                        checkEDT();
139                    }
140                });
141                EventQueue.invokeLater(new Runnable() {
142                    @Override
143                    public void run() {
144                        TestEventQueue teq = new TestEventQueue();
145                        EventQueue seq = Toolkit.getDefaultToolkit().getSystemEventQueue();
146                        try {
147                            seq.push(teq);
148                            checkEDT();
149                            EventQueue.invokeLater(new Runnable() {
150                                @Override
151                                public void run() {
152                                    d.dispose();
153                                    checkEDT();
154                                    synchronized (test3Lock) {
155                                        test3Sync = true;
156                                        test3Lock.notify();
157                                    }
158                                }
159                            });
160                        } finally {
161                            teq.pop();
162                        }
163                        checkEDT();
164                    }
165                });
166                checkEDT();
167            }
168        });
169        synchronized (test3Lock) {
170            while (!test3Sync) {
171                try {
172                    test3Lock.wait();
173                } catch (InterruptedException ie) {
174                    break;
175                }
176            }
177        }
178        // Make sure all the nested invokeLater/invokeAndWait are processed
179        EventQueue.invokeAndWait(new Runnable() {
180            @Override
181            public void run() {
182            }
183        });
184    }
185
186    private static void checkEDT() {
187        isEDT = isEDT && EventQueue.isDispatchThread();
188    }
189
190    private static class TestEventQueue extends EventQueue {
191        public TestEventQueue() {
192            super();
193        }
194        public void pop() {
195            super.pop();
196        }
197    }
198
199    private static class TestDialog extends Dialog {
200        private volatile boolean dialogShown = false;
201        private volatile boolean paintCalled = false;
202        public TestDialog() {
203            super(f, true);
204            setSize(240, 180);
205            setLocationRelativeTo(f);
206            addComponentListener(new ComponentAdapter() {
207                @Override
208                public void componentShown(ComponentEvent e) {
209                    if (paintCalled) {
210                        dispose();
211                    }
212                    dialogShown = true;
213                }
214            });
215        }
216        @Override
217        public void paint(Graphics g) {
218            if (dialogShown) {
219                dispose();
220            }
221            paintCalled = true;
222        }
223    }
224
225}
226