64 public AWTEvent getNested(AWTEvent sequencedEvent) {
65 return ((SequencedEvent)sequencedEvent).nested;
66 }
67 public boolean isSequencedEvent(AWTEvent event) {
68 return event instanceof SequencedEvent;
69 }
70
71 public AWTEvent create(AWTEvent event) {
72 return new SequencedEvent(event);
73 }
74 });
75 AccessController.doPrivileged(new PrivilegedAction<Object>() {
76 public Object run() {
77 fxAppThreadIsDispatchThread =
78 "true".equals(System.getProperty("javafx.embed.singleThread"));
79 return null;
80 }
81 });
82 }
83
84 /**
85 * Constructs a new SequencedEvent which will dispatch the specified
86 * nested event.
87 *
88 * @param nested the AWTEvent which this SequencedEvent's dispatch()
89 * method will dispatch
90 */
91 public SequencedEvent(AWTEvent nested) {
92 super(nested.getSource(), ID);
93 this.nested = nested;
94 // All AWTEvents that are wrapped in SequencedEvents are (at
95 // least currently) implicitly generated by the system
96 SunToolkit.setSystemGenerated(nested);
97
98 if (fxAppThreadIsDispatchThread) {
99 fxCheckSequenceThread = new Thread() {
100 @Override
101 public void run() {
102 while(!isFirstOrDisposed()) {
103 try {
118 * Dispatches the nested event after all previous nested events have been
119 * dispatched or disposed. If this method is invoked before all previous nested events
120 * have been dispatched, then this method blocks until such a point is
121 * reached.
122 * While waiting disposes nested events to disposed AppContext
123 *
124 * NOTE: Locking protocol. Since dispose() can get EventQueue lock,
125 * dispatch() shall never call dispose() while holding the lock on the list,
126 * as EventQueue lock is held during dispatching. The locks should be acquired
127 * in the same order.
128 */
129 public final void dispatch() {
130 try {
131 appContext = AppContext.getAppContext();
132
133 if (getFirst() != this) {
134 if (EventQueue.isDispatchThread()) {
135 if (Thread.currentThread() instanceof EventDispatchThread) {
136 EventDispatchThread edt = (EventDispatchThread)
137 Thread.currentThread();
138 edt.pumpEvents(ID, () -> !SequencedEvent.this.isFirstOrDisposed());
139 } else {
140 if (fxAppThreadIsDispatchThread) {
141 fxCheckSequenceThread.start();
142 try {
143 // check if event is dispatched or disposed
144 // but since this user app thread is same as
145 // dispatch thread in fx when run with
146 // javafx.embed.singleThread=true
147 // we do not wait infinitely to avoid deadlock
148 // as dispatch will ultimately be done by this thread
149 fxCheckSequenceThread.join(500);
150 } catch (InterruptedException e) {
151 }
152 }
153 }
154 } else {
155 while(!isFirstOrDisposed()) {
156 synchronized (SequencedEvent.class) {
157 try {
158 SequencedEvent.class.wait(1000);
|
64 public AWTEvent getNested(AWTEvent sequencedEvent) {
65 return ((SequencedEvent)sequencedEvent).nested;
66 }
67 public boolean isSequencedEvent(AWTEvent event) {
68 return event instanceof SequencedEvent;
69 }
70
71 public AWTEvent create(AWTEvent event) {
72 return new SequencedEvent(event);
73 }
74 });
75 AccessController.doPrivileged(new PrivilegedAction<Object>() {
76 public Object run() {
77 fxAppThreadIsDispatchThread =
78 "true".equals(System.getProperty("javafx.embed.singleThread"));
79 return null;
80 }
81 });
82 }
83
84 private static class SequencedEventsFilter implements EventFilter {
85 @Override
86 public FilterAction acceptEvent(AWTEvent ev) {
87 final int eventID = ev.getID();
88 if (eventID == ID || eventID == SentEvent.ID) {
89 return FilterAction.ACCEPT;
90 }
91 return FilterAction.REJECT;
92 }
93 }
94
95 /**
96 * Constructs a new SequencedEvent which will dispatch the specified
97 * nested event.
98 *
99 * @param nested the AWTEvent which this SequencedEvent's dispatch()
100 * method will dispatch
101 */
102 public SequencedEvent(AWTEvent nested) {
103 super(nested.getSource(), ID);
104 this.nested = nested;
105 // All AWTEvents that are wrapped in SequencedEvents are (at
106 // least currently) implicitly generated by the system
107 SunToolkit.setSystemGenerated(nested);
108
109 if (fxAppThreadIsDispatchThread) {
110 fxCheckSequenceThread = new Thread() {
111 @Override
112 public void run() {
113 while(!isFirstOrDisposed()) {
114 try {
129 * Dispatches the nested event after all previous nested events have been
130 * dispatched or disposed. If this method is invoked before all previous nested events
131 * have been dispatched, then this method blocks until such a point is
132 * reached.
133 * While waiting disposes nested events to disposed AppContext
134 *
135 * NOTE: Locking protocol. Since dispose() can get EventQueue lock,
136 * dispatch() shall never call dispose() while holding the lock on the list,
137 * as EventQueue lock is held during dispatching. The locks should be acquired
138 * in the same order.
139 */
140 public final void dispatch() {
141 try {
142 appContext = AppContext.getAppContext();
143
144 if (getFirst() != this) {
145 if (EventQueue.isDispatchThread()) {
146 if (Thread.currentThread() instanceof EventDispatchThread) {
147 EventDispatchThread edt = (EventDispatchThread)
148 Thread.currentThread();
149 edt.pumpEventsForFilter(() -> !SequencedEvent.this.isFirstOrDisposed(),
150 new SequencedEventsFilter());
151 } else {
152 if (fxAppThreadIsDispatchThread) {
153 fxCheckSequenceThread.start();
154 try {
155 // check if event is dispatched or disposed
156 // but since this user app thread is same as
157 // dispatch thread in fx when run with
158 // javafx.embed.singleThread=true
159 // we do not wait infinitely to avoid deadlock
160 // as dispatch will ultimately be done by this thread
161 fxCheckSequenceThread.join(500);
162 } catch (InterruptedException e) {
163 }
164 }
165 }
166 } else {
167 while(!isFirstOrDisposed()) {
168 synchronized (SequencedEvent.class) {
169 try {
170 SequencedEvent.class.wait(1000);
|