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