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 import java.util.LinkedList; 29 import sun.awt.AWTAccessor; 30 import sun.awt.AppContext; 31 import sun.awt.SunToolkit; 32 33 /** 34 * A mechanism for ensuring that a series of AWTEvents are executed in a 35 * precise order, even across multiple AppContexts. The nested events will be 36 * dispatched in the order in which their wrapping SequencedEvents were 37 * constructed. The only exception to this rule is if the peer of the target of 38 * the nested event was destroyed (with a call to Component.removeNotify) 39 * before the wrapping SequencedEvent was able to be dispatched. In this case, 40 * the nested event is never dispatched. 41 * 42 * @author David Mendenhall 43 */ 44 class SequencedEvent extends AWTEvent implements ActiveEvent { 45 /* 46 * serialVersionUID 47 */ 89 } 90 91 /** 92 * Dispatches the nested event after all previous nested events have been 93 * dispatched or disposed. If this method is invoked before all previous nested events 94 * have been dispatched, then this method blocks until such a point is 95 * reached. 96 * While waiting disposes nested events to disposed AppContext 97 * 98 * NOTE: Locking protocol. Since dispose() can get EventQueue lock, 99 * dispatch() shall never call dispose() while holding the lock on the list, 100 * as EventQueue lock is held during dispatching. The locks should be acquired 101 * in the same order. 102 */ 103 public final void dispatch() { 104 try { 105 appContext = AppContext.getAppContext(); 106 107 if (getFirst() != this) { 108 if (EventQueue.isDispatchThread()) { 109 EventDispatchThread edt = (EventDispatchThread) 110 Thread.currentThread(); 111 edt.pumpEvents(SentEvent.ID, new Conditional() { 112 public boolean evaluate() { 113 return !SequencedEvent.this.isFirstOrDisposed(); 114 } 115 }); 116 } else { 117 while(!isFirstOrDisposed()) { 118 synchronized (SequencedEvent.class) { 119 try { 120 SequencedEvent.class.wait(1000); 121 } catch (InterruptedException e) { 122 break; 123 } 124 } 125 } 126 } 127 } 128 129 if (!disposed) { 130 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 131 setCurrentSequencedEvent(this); 132 Toolkit.getEventQueue().dispatchEvent(nested); 133 } 134 } finally { 135 dispose(); | 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 import java.security.AccessController; 29 import java.security.PrivilegedAction; 30 import java.util.LinkedList; 31 import sun.awt.AWTAccessor; 32 import sun.awt.AppContext; 33 import sun.awt.SunToolkit; 34 35 /** 36 * A mechanism for ensuring that a series of AWTEvents are executed in a 37 * precise order, even across multiple AppContexts. The nested events will be 38 * dispatched in the order in which their wrapping SequencedEvents were 39 * constructed. The only exception to this rule is if the peer of the target of 40 * the nested event was destroyed (with a call to Component.removeNotify) 41 * before the wrapping SequencedEvent was able to be dispatched. In this case, 42 * the nested event is never dispatched. 43 * 44 * @author David Mendenhall 45 */ 46 class SequencedEvent extends AWTEvent implements ActiveEvent { 47 /* 48 * serialVersionUID 49 */ 91 } 92 93 /** 94 * Dispatches the nested event after all previous nested events have been 95 * dispatched or disposed. If this method is invoked before all previous nested events 96 * have been dispatched, then this method blocks until such a point is 97 * reached. 98 * While waiting disposes nested events to disposed AppContext 99 * 100 * NOTE: Locking protocol. Since dispose() can get EventQueue lock, 101 * dispatch() shall never call dispose() while holding the lock on the list, 102 * as EventQueue lock is held during dispatching. The locks should be acquired 103 * in the same order. 104 */ 105 public final void dispatch() { 106 try { 107 appContext = AppContext.getAppContext(); 108 109 if (getFirst() != this) { 110 if (EventQueue.isDispatchThread()) { 111 if (Thread.currentThread() instanceof EventDispatchThread) { 112 EventDispatchThread edt = (EventDispatchThread) 113 Thread.currentThread(); 114 edt.pumpEvents(SentEvent.ID, new Conditional() { 115 public boolean evaluate() { 116 return !SequencedEvent.this.isFirstOrDisposed(); 117 } 118 }); 119 } else { 120 EventQueue eventQueue = AccessController.doPrivileged( 121 (PrivilegedAction<EventQueue>) java.awt.Toolkit 122 .getDefaultToolkit()::getSystemEventQueue); 123 SecondaryLoop secondaryLoop = eventQueue.createSecondaryLoop(); 124 new Thread() { 125 @Override 126 public void run() { 127 while(!isFirstOrDisposed()) { 128 try { 129 Thread.sleep(1000); 130 } catch (InterruptedException e) { 131 break; 132 } 133 } 134 secondaryLoop.exit(); 135 } 136 }.start(); 137 secondaryLoop.enter(); 138 } 139 } else { 140 while(!isFirstOrDisposed()) { 141 synchronized (SequencedEvent.class) { 142 try { 143 SequencedEvent.class.wait(1000); 144 } catch (InterruptedException e) { 145 break; 146 } 147 } 148 } 149 } 150 } 151 152 if (!disposed) { 153 KeyboardFocusManager.getCurrentKeyboardFocusManager(). 154 setCurrentSequencedEvent(this); 155 Toolkit.getEventQueue().dispatchEvent(nested); 156 } 157 } finally { 158 dispose(); |