1 | // Copyright 2004-2007 Jean-Francois Poilpret |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | // Original copyright is held by Nathan Arthur |
16 | // [Java Specialists' Newsletter, Issue #75, 2003-07-29] |
17 | |
18 | package net.sourceforge.hivegui.autowait; |
19 | |
20 | import java.awt.AWTEvent; |
21 | import java.awt.EventQueue; |
22 | import java.awt.Toolkit; |
23 | import java.awt.event.InputEvent; |
24 | import java.util.ArrayList; |
25 | import java.util.List; |
26 | import java.util.Stack; |
27 | |
28 | public class CursorManager |
29 | { |
30 | public CursorManager(DelayTimer waitTimer) |
31 | { |
32 | _dispatchedEvents = new Stack<DispatchedEvent>(); |
33 | _waitTimer = waitTimer; |
34 | } |
35 | |
36 | private void cleanUp() |
37 | { |
38 | if (_dispatchedEvents.peek().resetCursor()) |
39 | { |
40 | clearQueueOfInputEvents(); |
41 | } |
42 | } |
43 | |
44 | private void clearQueueOfInputEvents() |
45 | { |
46 | EventQueue queue = Toolkit.getDefaultToolkit().getSystemEventQueue(); |
47 | synchronized (queue) |
48 | { |
49 | for (AWTEvent event: gatherNonInputEvents(queue)) |
50 | { |
51 | queue.postEvent(event); |
52 | } |
53 | } |
54 | } |
55 | |
56 | private List<AWTEvent> gatherNonInputEvents(EventQueue systemQueue) |
57 | { |
58 | List<AWTEvent> events = new ArrayList<AWTEvent>(); |
59 | while (systemQueue.peekEvent() != null) |
60 | { |
61 | try |
62 | { |
63 | AWTEvent nextEvent = systemQueue.getNextEvent(); |
64 | if (!(nextEvent instanceof InputEvent)) |
65 | { |
66 | events.add(nextEvent); |
67 | } |
68 | } |
69 | catch (InterruptedException ie) |
70 | { |
71 | Thread.currentThread().interrupt(); |
72 | } |
73 | } |
74 | return events; |
75 | } |
76 | |
77 | public void push(Object source) |
78 | { |
79 | if (_needsCleanup) |
80 | { |
81 | _waitTimer.stopTimer(); |
82 | // Correct the state when a modal dialog opened last time round |
83 | cleanUp(); |
84 | } |
85 | _dispatchedEvents.push(new DispatchedEvent(source)); |
86 | _needsCleanup = true; |
87 | } |
88 | |
89 | public void pop() |
90 | { |
91 | cleanUp(); |
92 | _dispatchedEvents.pop(); |
93 | if (!_dispatchedEvents.isEmpty()) |
94 | { |
95 | // This will be stopped if getNextEvent() is called - |
96 | // used to watch for modal dialogs closing |
97 | _waitTimer.startTimer(); |
98 | } |
99 | else |
100 | { |
101 | _needsCleanup = false; |
102 | } |
103 | } |
104 | |
105 | public void setCursor() |
106 | { |
107 | _dispatchedEvents.peek().setCursor(); |
108 | } |
109 | |
110 | private final DelayTimer _waitTimer; |
111 | private final Stack<DispatchedEvent> _dispatchedEvents; |
112 | private boolean _needsCleanup; |
113 | } |