Methods Summary |
---|
public final void | dispatch()Dispatches the nested event after all previous nested events have been
dispatched or disposed. If this method is invoked before all previous nested events
have been dispatched, then this method blocks until such a point is
reached.
While waiting disposes nested events to disposed AppContext
NOTE: Locking protocol. Since dispose() can get EventQueue lock,
dispatch() shall never call dispose() while holding the lock on the list,
as EventQueue lock is held during dispatching. The locks should be acquired
in the same order.
try {
appContext = AppContext.getAppContext();
if (getFirst() != this) {
if (EventQueue.isDispatchThread()) {
EventDispatchThread edt = (EventDispatchThread)
Thread.currentThread();
edt.pumpEvents(SentEvent.ID, new Conditional() {
public boolean evaluate() {
return !SequencedEvent.this.isFirstOrDisposed();
}
});
} else {
while(!isFirstOrDisposed()) {
synchronized (SequencedEvent.class) {
try {
SequencedEvent.class.wait(1000);
} catch (InterruptedException e) {
break;
}
}
}
}
}
if (!disposed) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setCurrentSequencedEvent(this);
Toolkit.getEventQueue().dispatchEvent(nested);
}
} finally {
dispose();
}
|
final void | dispose()Disposes of this instance. This method is invoked once the nested event
has been dispatched and handled, or when the peer of the target of the
nested event has been disposed with a call to Component.removeNotify.
NOTE: Locking protocol. Since SunToolkit.postEvent can get EventQueue lock,
it shall never be called while holding the lock on the list,
as EventQueue lock is held during dispatching and dispatch() will get
lock on the list. The locks should be acquired in the same order.
synchronized (SequencedEvent.class) {
if (disposed) {
return;
}
if (KeyboardFocusManager.getCurrentKeyboardFocusManager().
getCurrentSequencedEvent() == this) {
KeyboardFocusManager.getCurrentKeyboardFocusManager().
setCurrentSequencedEvent(null);
}
disposed = true;
}
// Wake myself up
if (appContext != null) {
SunToolkit.postEvent(appContext, new SentEvent());
}
SequencedEvent next = null;
synchronized (SequencedEvent.class) {
SequencedEvent.class.notifyAll();
if (list.getFirst() == this) {
list.removeFirst();
if (!list.isEmpty()) {
next = (SequencedEvent)list.getFirst();
}
} else {
list.remove(this);
}
}
// Wake up waiting threads
if (next != null && next.appContext != null) {
SunToolkit.postEvent(next.appContext, new SentEvent());
}
|
private static final synchronized java.awt.SequencedEvent | getFirst()
return (SequencedEvent)list.getFirst();
|
private static final java.awt.SequencedEvent | getFirstWithContext()
SequencedEvent first = getFirst();
while(isOwnerAppContextDisposed(first)) {
first.dispose();
first = getFirst();
}
return first;
|
public final boolean | isFirstOrDisposed()Sequenced events are dispatched in order, so we cannot dispatch
until we are the first sequenced event in the queue (i.e. it's our
turn). But while we wait for our turn to dispatch, the event
could have been disposed for a number of reasons.
if (disposed) {
return true;
}
// getFirstWithContext can dispose this
return this == getFirstWithContext() || disposed;
|
private static final boolean | isOwnerAppContextDisposed(java.awt.SequencedEvent se)true only if event exists and nested source appContext is disposed.
if (se != null) {
Object target = se.nested.getSource();
if (target instanceof Component) {
return ((Component)target).appContext.isDisposed();
}
}
return false;
|