Source Code Cross Referenced for SequencedEvent.java in  » JDK-Core » AWT » java » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. JDK Core
2. JDK Modules
3. JDK Modules com.sun
4. JDK Modules com.sun.java
5. JDK Modules Platform
6. JDK Modules sun
7. Open Source Build
8. Open Source Graphic Library
9. Open Source IDE Eclipse
10. Open Source J2EE
11. Open Source JDBC Driver
12. Open Source Library
13. Open Source Library Database
14. Open Source Net
15. Open Source Script
16. Science
17. Security
18. Sevlet Container
19. SUN GlassFish
20. Swing Library
21. Web Services apache cxf 2.0.1
22. Web Services AXIS2
23. XML
Microsoft Office Word 2007 Tutorial
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java Source Code / Java Documentation » JDK Core » AWT » java.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2000-2007 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package java.awt;
027:
028:        import java.util.LinkedList;
029:        import sun.awt.AppContext;
030:        import sun.awt.SunToolkit;
031:
032:        /**
033:         * A mechanism for ensuring that a series of AWTEvents are executed in a
034:         * precise order, even across multiple AppContexts. The nested events will be
035:         * dispatched in the order in which their wrapping SequencedEvents were
036:         * constructed. The only exception to this rule is if the peer of the target of
037:         * the nested event was destroyed (with a call to Component.removeNotify)
038:         * before the wrapping SequencedEvent was able to be dispatched. In this case,
039:         * the nested event is never dispatched.
040:         *
041:         * @version 1.20, 06/05/07
042:         * @author David Mendenhall
043:         */
044:        class SequencedEvent extends AWTEvent implements  ActiveEvent {
045:            /*
046:             * serialVersionUID
047:             */
048:            private static final long serialVersionUID = 547742659238625067L;
049:
050:            private static final int ID = java.awt.event.FocusEvent.FOCUS_LAST + 1;
051:            private static final LinkedList list = new LinkedList();
052:
053:            private final AWTEvent nested;
054:            private AppContext appContext;
055:            private boolean disposed;
056:
057:            /**
058:             * Constructs a new SequencedEvent which will dispatch the specified
059:             * nested event.
060:             *
061:             * @param nested the AWTEvent which this SequencedEvent's dispatch()
062:             *        method will dispatch
063:             */
064:            public SequencedEvent(AWTEvent nested) {
065:                super (nested.getSource(), ID);
066:                this .nested = nested;
067:                synchronized (SequencedEvent.class) {
068:                    list.add(this );
069:                }
070:            }
071:
072:            /**
073:             * Dispatches the nested event after all previous nested events have been
074:             * dispatched or disposed. If this method is invoked before all previous nested events
075:             * have been dispatched, then this method blocks until such a point is
076:             * reached.
077:             * While waiting disposes nested events to disposed AppContext
078:             *
079:             * NOTE: Locking protocol.  Since dispose() can get EventQueue lock, 
080:             * dispatch() shall never call dispose() while holding the lock on the list, 
081:             * as EventQueue lock is held during dispatching.  The locks should be acquired 
082:             * in the same order.
083:             */
084:            public final void dispatch() {
085:                try {
086:                    appContext = AppContext.getAppContext();
087:
088:                    if (getFirst() != this ) {
089:                        if (EventQueue.isDispatchThread()) {
090:                            EventDispatchThread edt = (EventDispatchThread) Thread
091:                                    .currentThread();
092:                            edt.pumpEvents(SentEvent.ID, new Conditional() {
093:                                public boolean evaluate() {
094:                                    return !SequencedEvent.this 
095:                                            .isFirstOrDisposed();
096:                                }
097:                            });
098:                        } else {
099:                            while (!isFirstOrDisposed()) {
100:                                synchronized (SequencedEvent.class) {
101:                                    try {
102:                                        SequencedEvent.class.wait(1000);
103:                                    } catch (InterruptedException e) {
104:                                        break;
105:                                    }
106:                                }
107:                            }
108:                        }
109:                    }
110:
111:                    if (!disposed) {
112:                        KeyboardFocusManager.getCurrentKeyboardFocusManager()
113:                                .setCurrentSequencedEvent(this );
114:                        Toolkit.getEventQueue().dispatchEvent(nested);
115:                    }
116:                } finally {
117:                    dispose();
118:                }
119:            }
120:
121:            /**
122:             * true only if event exists and nested source appContext is disposed.
123:             */
124:            private final static boolean isOwnerAppContextDisposed(
125:                    SequencedEvent se) {
126:                if (se != null) {
127:                    Object target = se.nested.getSource();
128:                    if (target instanceof  Component) {
129:                        return ((Component) target).appContext.isDisposed();
130:                    }
131:                }
132:                return false;
133:            }
134:
135:            /**
136:             * Sequenced events are dispatched in order, so we cannot dispatch
137:             * until we are the first sequenced event in the queue (i.e. it's our
138:             * turn).  But while we wait for our turn to dispatch, the event
139:             * could have been disposed for a number of reasons.
140:             */
141:            public final boolean isFirstOrDisposed() {
142:                if (disposed) {
143:                    return true;
144:                }
145:                // getFirstWithContext can dispose this
146:                return this  == getFirstWithContext() || disposed;
147:            }
148:
149:            private final synchronized static SequencedEvent getFirst() {
150:                return (SequencedEvent) list.getFirst();
151:            }
152:
153:            /* Disposes all events from disposed AppContext 
154:             * return first valid event
155:             */
156:            private final static SequencedEvent getFirstWithContext() {
157:                SequencedEvent first = getFirst();
158:                while (isOwnerAppContextDisposed(first)) {
159:                    first.dispose();
160:                    first = getFirst();
161:                }
162:                return first;
163:            }
164:
165:            /**
166:             * Disposes of this instance. This method is invoked once the nested event
167:             * has been dispatched and handled, or when the peer of the target of the
168:             * nested event has been disposed with a call to Component.removeNotify.
169:             *
170:             * NOTE: Locking protocol.  Since SunToolkit.postEvent can get EventQueue lock, 
171:             * it shall never be called while holding the lock on the list, 
172:             * as EventQueue lock is held during dispatching and dispatch() will get 
173:             * lock on the list. The locks should be acquired in the same order.
174:             */
175:            final void dispose() {
176:                synchronized (SequencedEvent.class) {
177:                    if (disposed) {
178:                        return;
179:                    }
180:                    if (KeyboardFocusManager.getCurrentKeyboardFocusManager()
181:                            .getCurrentSequencedEvent() == this ) {
182:                        KeyboardFocusManager.getCurrentKeyboardFocusManager()
183:                                .setCurrentSequencedEvent(null);
184:                    }
185:                    disposed = true;
186:                }
187:                // Wake myself up
188:                if (appContext != null) {
189:                    SunToolkit.postEvent(appContext, new SentEvent());
190:                }
191:
192:                SequencedEvent next = null;
193:
194:                synchronized (SequencedEvent.class) {
195:                    SequencedEvent.class.notifyAll();
196:
197:                    if (list.getFirst() == this ) {
198:                        list.removeFirst();
199:
200:                        if (!list.isEmpty()) {
201:                            next = (SequencedEvent) list.getFirst();
202:                        }
203:                    } else {
204:                        list.remove(this );
205:                    }
206:                }
207:                // Wake up waiting threads
208:                if (next != null && next.appContext != null) {
209:                    SunToolkit.postEvent(next.appContext, new SentEvent());
210:                }
211:            }
212:        }
w___ww___.j___av___a_2_s__.c_om | Contact Us
Copyright 2003 - 08 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.