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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.awt; 27 28 /** 29 * A helper interface to run the nested event loop. 30 * <p> 31 * Objects that implement this interface are created with the 32 * {@link EventQueue#createSecondaryLoop} method. The interface 33 * provides two methods, {@link #enter} and {@link #exit}, 34 * which can be used to start and stop the event loop. 35 * <p> 36 * When the {@link #enter} method is called, the current 37 * thread is blocked until the loop is terminated by the 38 * {@link #exit} method. Also, a new event loop is started 39 * on the event dispatch thread, which may or may not be 40 * the current thread. The loop can be terminated on any 41 * thread by calling its {@link #exit} method. After the 42 * loop is terminated, the {@code SecondaryLoop} object can 43 * be reused to run a new nested event loop. 44 * <p> 45 * A typical use case of applying this interface is AWT 46 * and Swing modal dialogs. When a modal dialog is shown on 47 * the event dispatch thread, it enters a new secondary loop. 48 * Later, when the dialog is hidden or disposed, it exits 49 * the loop, and the thread continues its execution. 50 * <p> 51 * The following example illustrates a simple use case of 52 * secondary loops: 53 * 54 * <pre> 55 * SecondaryLoop loop; 56 * 57 * JButton jButton = new JButton("Button"); 58 * jButton.addActionListener(new ActionListener() { 59 * {@code @Override} 60 * public void actionPerformed(ActionEvent e) { 61 * Toolkit tk = Toolkit.getDefaultToolkit(); 62 * EventQueue eq = tk.getSystemEventQueue(); 63 * loop = eq.createSecondaryLoop(); 64 * 65 * // Spawn a new thread to do the work 66 * Thread worker = new WorkerThread(); 67 * worker.start(); 68 * 69 * // Enter the loop to block the current event 70 * // handler, but leave UI responsive 71 * if (!loop.enter()) { 72 * // Report an error 73 * } 74 * } 75 * }); 76 * 77 * class WorkerThread extends Thread { 78 * {@code @Override} 79 * public void run() { 80 * // Perform calculations 81 * doSomethingUseful(); 82 * 83 * // Exit the loop 84 * loop.exit(); 85 * } 86 * } 87 * </pre> 88 * 89 * @see Dialog#show 90 * @see EventQueue#createSecondaryLoop 91 * @see Toolkit#getSystemEventQueue 92 * 93 * @author Anton Tarasov, Artem Ananiev 94 * 95 * @since 1.7 96 */ 97 public interface SecondaryLoop { 98 99 /** 100 * Blocks the execution of the current thread and enters a new 101 * secondary event loop on the event dispatch thread. 102 * <p> 103 * This method can be called by any thread including the event 104 * dispatch thread. This thread will be blocked until the {@link 105 * #exit} method is called or the loop is terminated. A new 106 * secondary loop will be created on the event dispatch thread 107 * for dispatching events in either case. 108 * <p> 109 * This method can only start one new event loop at a time per 110 * object. If a secondary event loop has already been started 111 * by this object and is currently still running, this method 112 * returns {@code false} to indicate that it was not successful 113 * in starting a new event loop. Otherwise, this method blocks 114 * the calling thread and later returns {@code true} when the 115 * new event loop is terminated. At such time, this object can 116 * again be used to start another new event loop. 117 * 118 * @return {@code true} after termination of the secondary loop, 119 * if the secondary loop was started by this call, 120 * {@code false} otherwise 121 */ enter()122 public boolean enter(); 123 124 /** 125 * Unblocks the execution of the thread blocked by the {@link 126 * #enter} method and exits the secondary loop. 127 * <p> 128 * This method resumes the thread that called the {@link #enter} 129 * method and exits the secondary loop that was created when 130 * the {@link #enter} method was invoked. 131 * <p> 132 * Note that if any other secondary loop is started while this 133 * loop is running, the blocked thread will not resume execution 134 * until the nested loop is terminated. 135 * <p> 136 * If this secondary loop has not been started with the {@link 137 * #enter} method, or this secondary loop has already finished 138 * with the {@link #exit} method, this method returns {@code 139 * false}, otherwise {@code true} is returned. 140 * 141 * @return {@code true} if this loop was previously started and 142 * has not yet been finished with the {@link #exit} method, 143 * {@code false} otherwise 144 */ exit()145 public boolean exit(); 146 147 } 148