719 * Called from dispatchEvent() under a correct AccessControlContext
720 */
721 private void dispatchEventImpl(final AWTEvent event, final Object src) {
722 event.isPosted = true;
723 if (event instanceof ActiveEvent) {
724 // This could become the sole method of dispatching in time.
725 setCurrentEventAndMostRecentTimeImpl(event);
726 ((ActiveEvent)event).dispatch();
727 } else if (src instanceof Component) {
728 ((Component)src).dispatchEvent(event);
729 event.dispatched();
730 } else if (src instanceof MenuComponent) {
731 ((MenuComponent)src).dispatchEvent(event);
732 } else if (src instanceof TrayIcon) {
733 ((TrayIcon)src).dispatchEvent(event);
734 } else if (src instanceof AWTAutoShutdown) {
735 if (noEvents()) {
736 dispatchThread.stopDispatching();
737 }
738 } else {
739 if (eventLog.isLoggable(PlatformLogger.FINE)) {
740 eventLog.fine("Unable to dispatch event: " + event);
741 }
742 }
743 }
744
745 /**
746 * Returns the timestamp of the most recent event that had a timestamp, and
747 * that was dispatched from the <code>EventQueue</code> associated with the
748 * calling thread. If an event with a timestamp is currently being
749 * dispatched, its timestamp will be returned. If no events have yet
750 * been dispatched, the EventQueue's initialization time will be
751 * returned instead.In the current version of
752 * the JDK, only <code>InputEvent</code>s,
753 * <code>ActionEvent</code>s, and <code>InvocationEvent</code>s have
754 * timestamps; however, future versions of the JDK may add timestamps to
755 * additional event types. Note that this method should only be invoked
756 * from an application's {@link #isDispatchThread event dispatching thread}.
757 * If this method is
758 * invoked from another thread, the current system time (as reported by
759 * <code>System.currentTimeMillis()</code>) will be returned instead.
817 return (Thread.currentThread() == dispatchThread)
818 ? currentEvent.get()
819 : null;
820 } finally {
821 pushPopLock.unlock();
822 }
823 }
824
825 /**
826 * Replaces the existing <code>EventQueue</code> with the specified one.
827 * Any pending events are transferred to the new <code>EventQueue</code>
828 * for processing by it.
829 *
830 * @param newEventQueue an <code>EventQueue</code>
831 * (or subclass thereof) instance to be use
832 * @see java.awt.EventQueue#pop
833 * @throws NullPointerException if <code>newEventQueue</code> is <code>null</code>
834 * @since 1.2
835 */
836 public void push(EventQueue newEventQueue) {
837 if (eventLog.isLoggable(PlatformLogger.FINE)) {
838 eventLog.fine("EventQueue.push(" + newEventQueue + ")");
839 }
840
841 pushPopLock.lock();
842 try {
843 EventQueue topQueue = this;
844 while (topQueue.nextQueue != null) {
845 topQueue = topQueue.nextQueue;
846 }
847
848 if ((topQueue.dispatchThread != null) &&
849 (topQueue.dispatchThread.getEventQueue() == this))
850 {
851 newEventQueue.dispatchThread = topQueue.dispatchThread;
852 topQueue.dispatchThread.setEventQueue(newEventQueue);
853 }
854
855 // Transfer all events forward to new EventQueue.
856 while (topQueue.peekEvent() != null) {
857 try {
858 // Use getNextEventPrivate() as it doesn't call flushPendingEvents()
859 newEventQueue.postEventPrivate(topQueue.getNextEventPrivate());
860 } catch (InterruptedException ie) {
861 if (eventLog.isLoggable(PlatformLogger.FINE)) {
862 eventLog.fine("Interrupted push", ie);
863 }
864 }
865 }
866
867 // Wake up EDT waiting in getNextEvent(), so it can
868 // pick up a new EventQueue. Post the waking event before
869 // topQueue.nextQueue is assigned, otherwise the event would
870 // go newEventQueue
871 topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
872
873 newEventQueue.previousQueue = topQueue;
874 topQueue.nextQueue = newEventQueue;
875
876 AppContext appContext = AppContext.getAppContext();
877 if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
878 appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
879 }
880
881 pushPopCond.signalAll();
882 } finally {
883 pushPopLock.unlock();
884 }
885 }
886
887 /**
888 * Stops dispatching events using this <code>EventQueue</code>.
889 * Any pending events are transferred to the previous
890 * <code>EventQueue</code> for processing.
891 * <p>
892 * Warning: To avoid deadlock, do not declare this method
893 * synchronized in a subclass.
894 *
895 * @exception EmptyStackException if no previous push was made
896 * on this <code>EventQueue</code>
897 * @see java.awt.EventQueue#push
898 * @since 1.2
899 */
900 protected void pop() throws EmptyStackException {
901 if (eventLog.isLoggable(PlatformLogger.FINE)) {
902 eventLog.fine("EventQueue.pop(" + this + ")");
903 }
904
905 pushPopLock.lock();
906 try {
907 EventQueue topQueue = this;
908 while (topQueue.nextQueue != null) {
909 topQueue = topQueue.nextQueue;
910 }
911 EventQueue prevQueue = topQueue.previousQueue;
912 if (prevQueue == null) {
913 throw new EmptyStackException();
914 }
915
916 topQueue.previousQueue = null;
917 prevQueue.nextQueue = null;
918
919 // Transfer all events back to previous EventQueue.
920 while (topQueue.peekEvent() != null) {
921 try {
922 prevQueue.postEventPrivate(topQueue.getNextEventPrivate());
923 } catch (InterruptedException ie) {
924 if (eventLog.isLoggable(PlatformLogger.FINE)) {
925 eventLog.fine("Interrupted pop", ie);
926 }
927 }
928 }
929
930 if ((topQueue.dispatchThread != null) &&
931 (topQueue.dispatchThread.getEventQueue() == this))
932 {
933 prevQueue.dispatchThread = topQueue.dispatchThread;
934 topQueue.dispatchThread.setEventQueue(prevQueue);
935 }
936
937 AppContext appContext = AppContext.getAppContext();
938 if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
939 appContext.put(AppContext.EVENT_QUEUE_KEY, prevQueue);
940 }
941
942 // Wake up EDT waiting in getNextEvent(), so it can
943 // pick up a new EventQueue
944 topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
|
719 * Called from dispatchEvent() under a correct AccessControlContext
720 */
721 private void dispatchEventImpl(final AWTEvent event, final Object src) {
722 event.isPosted = true;
723 if (event instanceof ActiveEvent) {
724 // This could become the sole method of dispatching in time.
725 setCurrentEventAndMostRecentTimeImpl(event);
726 ((ActiveEvent)event).dispatch();
727 } else if (src instanceof Component) {
728 ((Component)src).dispatchEvent(event);
729 event.dispatched();
730 } else if (src instanceof MenuComponent) {
731 ((MenuComponent)src).dispatchEvent(event);
732 } else if (src instanceof TrayIcon) {
733 ((TrayIcon)src).dispatchEvent(event);
734 } else if (src instanceof AWTAutoShutdown) {
735 if (noEvents()) {
736 dispatchThread.stopDispatching();
737 }
738 } else {
739 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
740 eventLog.fine("Unable to dispatch event: " + event);
741 }
742 }
743 }
744
745 /**
746 * Returns the timestamp of the most recent event that had a timestamp, and
747 * that was dispatched from the <code>EventQueue</code> associated with the
748 * calling thread. If an event with a timestamp is currently being
749 * dispatched, its timestamp will be returned. If no events have yet
750 * been dispatched, the EventQueue's initialization time will be
751 * returned instead.In the current version of
752 * the JDK, only <code>InputEvent</code>s,
753 * <code>ActionEvent</code>s, and <code>InvocationEvent</code>s have
754 * timestamps; however, future versions of the JDK may add timestamps to
755 * additional event types. Note that this method should only be invoked
756 * from an application's {@link #isDispatchThread event dispatching thread}.
757 * If this method is
758 * invoked from another thread, the current system time (as reported by
759 * <code>System.currentTimeMillis()</code>) will be returned instead.
817 return (Thread.currentThread() == dispatchThread)
818 ? currentEvent.get()
819 : null;
820 } finally {
821 pushPopLock.unlock();
822 }
823 }
824
825 /**
826 * Replaces the existing <code>EventQueue</code> with the specified one.
827 * Any pending events are transferred to the new <code>EventQueue</code>
828 * for processing by it.
829 *
830 * @param newEventQueue an <code>EventQueue</code>
831 * (or subclass thereof) instance to be use
832 * @see java.awt.EventQueue#pop
833 * @throws NullPointerException if <code>newEventQueue</code> is <code>null</code>
834 * @since 1.2
835 */
836 public void push(EventQueue newEventQueue) {
837 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
838 eventLog.fine("EventQueue.push(" + newEventQueue + ")");
839 }
840
841 pushPopLock.lock();
842 try {
843 EventQueue topQueue = this;
844 while (topQueue.nextQueue != null) {
845 topQueue = topQueue.nextQueue;
846 }
847
848 if ((topQueue.dispatchThread != null) &&
849 (topQueue.dispatchThread.getEventQueue() == this))
850 {
851 newEventQueue.dispatchThread = topQueue.dispatchThread;
852 topQueue.dispatchThread.setEventQueue(newEventQueue);
853 }
854
855 // Transfer all events forward to new EventQueue.
856 while (topQueue.peekEvent() != null) {
857 try {
858 // Use getNextEventPrivate() as it doesn't call flushPendingEvents()
859 newEventQueue.postEventPrivate(topQueue.getNextEventPrivate());
860 } catch (InterruptedException ie) {
861 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
862 eventLog.fine("Interrupted push", ie);
863 }
864 }
865 }
866
867 // Wake up EDT waiting in getNextEvent(), so it can
868 // pick up a new EventQueue. Post the waking event before
869 // topQueue.nextQueue is assigned, otherwise the event would
870 // go newEventQueue
871 topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
872
873 newEventQueue.previousQueue = topQueue;
874 topQueue.nextQueue = newEventQueue;
875
876 AppContext appContext = AppContext.getAppContext();
877 if (appContext.get(AppContext.EVENT_QUEUE_KEY) == topQueue) {
878 appContext.put(AppContext.EVENT_QUEUE_KEY, newEventQueue);
879 }
880
881 pushPopCond.signalAll();
882 } finally {
883 pushPopLock.unlock();
884 }
885 }
886
887 /**
888 * Stops dispatching events using this <code>EventQueue</code>.
889 * Any pending events are transferred to the previous
890 * <code>EventQueue</code> for processing.
891 * <p>
892 * Warning: To avoid deadlock, do not declare this method
893 * synchronized in a subclass.
894 *
895 * @exception EmptyStackException if no previous push was made
896 * on this <code>EventQueue</code>
897 * @see java.awt.EventQueue#push
898 * @since 1.2
899 */
900 protected void pop() throws EmptyStackException {
901 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
902 eventLog.fine("EventQueue.pop(" + this + ")");
903 }
904
905 pushPopLock.lock();
906 try {
907 EventQueue topQueue = this;
908 while (topQueue.nextQueue != null) {
909 topQueue = topQueue.nextQueue;
910 }
911 EventQueue prevQueue = topQueue.previousQueue;
912 if (prevQueue == null) {
913 throw new EmptyStackException();
914 }
915
916 topQueue.previousQueue = null;
917 prevQueue.nextQueue = null;
918
919 // Transfer all events back to previous EventQueue.
920 while (topQueue.peekEvent() != null) {
921 try {
922 prevQueue.postEventPrivate(topQueue.getNextEventPrivate());
923 } catch (InterruptedException ie) {
924 if (eventLog.isLoggable(PlatformLogger.Level.FINE)) {
925 eventLog.fine("Interrupted pop", ie);
926 }
927 }
928 }
929
930 if ((topQueue.dispatchThread != null) &&
931 (topQueue.dispatchThread.getEventQueue() == this))
932 {
933 prevQueue.dispatchThread = topQueue.dispatchThread;
934 topQueue.dispatchThread.setEventQueue(prevQueue);
935 }
936
937 AppContext appContext = AppContext.getAppContext();
938 if (appContext.get(AppContext.EVENT_QUEUE_KEY) == this) {
939 appContext.put(AppContext.EVENT_QUEUE_KEY, prevQueue);
940 }
941
942 // Wake up EDT waiting in getNextEvent(), so it can
943 // pick up a new EventQueue
944 topQueue.postEventPrivate(new InvocationEvent(topQueue, dummyRunnable));
|