Source Code Cross Referenced for LightweightDispatcher.java in  » 6.0-JDK-Modules » j2me » java » awt » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » 6.0 JDK Modules » j2me » java.awt 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)LightweightDispatcher.java	1.15 06/10/10
003:         *
004:         * Copyright  1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006:         * 
007:         * This program is free software; you can redistribute it and/or
008:         * modify it under the terms of the GNU General Public License version
009:         * 2 only, as published by the Free Software Foundation. 
010:         * 
011:         * This program is distributed in the hope that it will be useful, but
012:         * WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014:         * General Public License version 2 for more details (a copy is
015:         * included at /legal/license.txt). 
016:         * 
017:         * You should have received a copy of the GNU General Public License
018:         * version 2 along with this work; if not, write to the Free Software
019:         * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020:         * 02110-1301 USA 
021:         * 
022:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023:         * Clara, CA 95054 or visit www.sun.com if you need additional
024:         * information or have any questions. 
025:         *
026:         */
027:
028:        package java.awt;
029:
030:        import java.awt.event.*;
031:        import sun.awt.peer.*;
032:
033:        /**
034:         * Class to manage the dispatching of events to the lightweight
035:         * components contained by a native container.
036:         *
037:         * @author Timothy Prinzing
038:         */
039:        class LightweightDispatcher implements  java.io.Serializable,
040:                AWTEventListener {
041:            /*
042:             * JDK 1.1 serialVersionUID
043:             */
044:            private static final long serialVersionUID = 5184291520170872969L;
045:            /*
046:             * Our own mouse event for when we're dragged over from another hw container
047:             */
048:            private static final int LWD_MOUSE_DRAGGED_OVER = AWTEvent.RESERVED_ID_MAX + 1;
049:
050:            LightweightDispatcher(Container nativeContainer) {
051:                this .nativeContainer = nativeContainer;
052:                mouseEventTarget = null;
053:                eventMask = 0;
054:            }
055:
056:            /*
057:             * Disposes any external resources allocated by the dispatcher
058:             */
059:            void dispose() {
060:                stopListeningForOtherDrags();
061:            }
062:
063:            /**
064:             * Enables events to lightweight components.
065:             */
066:            void enableEvents(long events) {
067:                eventMask |= events;
068:            }
069:
070:            /**
071:             * Dispatches an event to a lightweight sub-component if necessary, and
072:             * returns whether or not the event was forwarded to a lightweight
073:             * sub-component.
074:             *
075:             * @param e the event
076:             */
077:            boolean dispatchEvent(AWTEvent e) {
078:                boolean ret = false;
079:                if ((eventMask & PROXY_EVENT_MASK) != 0) {
080:                    if ((e instanceof  MouseEvent)
081:                            && ((eventMask & MOUSE_MASK) != 0)) {
082:                        MouseEvent me = (MouseEvent) e;
083:                        ret = processMouseEvent(me);
084:                    }
085:                }
086:                if (e instanceof  MouseEvent) {
087:                    // find out what component the mouse moved in
088:                    MouseEvent me = (MouseEvent) e;
089:                    if (me.getID() == MouseEvent.MOUSE_MOVED) {
090:                        cursorOn = nativeContainer.getCursorTarget(me.getX(),
091:                                me.getY());
092:                        // 6201639
093:                        // cursorOn can be null in the following cases
094:                        // 1) mouse position is on the nativeContainer
095:                        // 2) mouse position is on a heavyweight
096:                        // The updateCursor() method always treats a null argument
097:                        // as the nativeContainer, so we need to make this non-null
098:                        // check. 
099:                        // (See the related fix in Container.getCursorTarget())
100:                        if (cursorOn != null) {
101:                            // 6201639
102:                            updateCursor(cursorOn);
103:                        }
104:                    }
105:                }
106:                return ret;
107:            }
108:
109:            /**
110:             * This method attempts to distribute a mouse event to a lightweight
111:             * component.  It tries to avoid doing any unnecessary probes down
112:             * into the component tree to minimize the overhead of determining
113:             * where to route the event, since mouse movement events tend to
114:             * come in large and frequent amounts.
115:             */
116:            private boolean processMouseEvent(MouseEvent e) {
117:                int id = e.getID();
118:                Component targetOver;
119:                Component lwOver;
120:                targetOver = nativeContainer.getMouseEventTarget(e.getX(), e
121:                        .getY(), true);
122:                trackMouseEnterExit(targetOver, e);
123:
124:                if (id == MouseEvent.MOUSE_MOVED
125:                        || id == MouseEvent.MOUSE_PRESSED
126:                        || id == MouseEvent.MOUSE_RELEASED) {
127:                    lwOver = (targetOver != nativeContainer) ? targetOver
128:                            : null;
129:                    setMouseTarget(lwOver, e);
130:                }
131:                if (mouseEventTarget != null) {
132:                    // we are currently forwarding to some component, check
133:                    // to see if we should continue to forward.
134:                    switch (id) {
135:                    case MouseEvent.MOUSE_DRAGGED:
136:                        if (dragging) {
137:                            retargetMouseEvent(mouseEventTarget, id, e);
138:                        }
139:                        break;
140:
141:                    case MouseEvent.MOUSE_PRESSED:
142:                        dragging = true;
143:                        retargetMouseEvent(mouseEventTarget, id, e);
144:                        break;
145:
146:                    case MouseEvent.MOUSE_RELEASED:
147:                        dragging = false;
148:                        retargetMouseEvent(mouseEventTarget, id, e);
149:                        break;
150:
151:                    // MOUSE_CLICKED should never be dispatched to a Component
152:                    // other than that which received the MOUSE_PRESSED event.  If the
153:                    // mouse is now over a different Component, don't dispatch the event.
154:                    // The previous fix for a similar problem was associated with bug
155:                    // 4155217.        
156:                    case MouseEvent.MOUSE_CLICKED:
157:                        if (targetOver == mouseEventTarget) {
158:                            retargetMouseEvent(mouseEventTarget, id, e);
159:                        }
160:                        break;
161:
162:                    case MouseEvent.MOUSE_ENTERED:
163:                        break;
164:
165:                    case MouseEvent.MOUSE_EXITED:
166:                        if (!dragging) {
167:                            setMouseTarget(null, e);
168:                        }
169:                        break;
170:
171:                    case MouseEvent.MOUSE_MOVED:
172:                        retargetMouseEvent(mouseEventTarget, id, e);
173:                        break;
174:                    }
175:                    e.consume();
176:                }
177:                return e.isConsumed();
178:            }
179:
180:            /**
181:             * Change the current target of mouse events.
182:             */
183:            private void setMouseTarget(Component target, MouseEvent e) {
184:                if (target != mouseEventTarget) {
185:                    //System.out.println("setMouseTarget: " + target);
186:                    mouseEventTarget = target;
187:                }
188:            }
189:
190:            /*
191:             * Generates enter/exit events as mouse moves over lw components
192:             * @param targetOver	Target mouse is over (including native container)
193:             * @param e			Mouse event in native container
194:             */
195:            private void trackMouseEnterExit(Component targetOver, MouseEvent e) {
196:                Component targetEnter = null;
197:                int id = e.getID();
198:                if (id != MouseEvent.MOUSE_EXITED
199:                        && id != MouseEvent.MOUSE_DRAGGED
200:                        && id != LWD_MOUSE_DRAGGED_OVER
201:                        && isMouseInNativeContainer == false) {
202:                    // any event but an exit or drag means we're in the native container
203:                    isMouseInNativeContainer = true;
204:                    startListeningForOtherDrags();
205:                } else if (id == MouseEvent.MOUSE_EXITED) {
206:                    isMouseInNativeContainer = false;
207:                    stopListeningForOtherDrags();
208:                }
209:                if (isMouseInNativeContainer) {
210:                    targetEnter = targetOver;
211:                }
212:                //System.out.println("targetEnter = " + targetEnter);
213:                //System.out.println("targetLastEntered = " + targetLastEntered);
214:
215:                if (targetLastEntered == targetEnter) {
216:                    return;
217:                }
218:                retargetMouseEvent(targetLastEntered, MouseEvent.MOUSE_EXITED,
219:                        e);
220:                if (id == MouseEvent.MOUSE_EXITED) {
221:                    // consume native exit event if we generate one
222:                    e.consume();
223:                }
224:                retargetMouseEvent(targetEnter, MouseEvent.MOUSE_ENTERED, e);
225:                if (id == MouseEvent.MOUSE_ENTERED) {
226:                    // consume native enter event if we generate one
227:                    e.consume();
228:                }
229:                //System.out.println("targetLastEntered: " + targetLastEntered);
230:                targetLastEntered = targetEnter;
231:            }
232:
233:            private void startListeningForOtherDrags() {
234:                java.security.AccessController
235:                        .doPrivileged(new java.security.PrivilegedAction() {
236:                            public Object run() {
237:                                nativeContainer
238:                                        .getToolkit()
239:                                        .addAWTEventListener(
240:                                                LightweightDispatcher.this ,
241:                                                AWTEvent.MOUSE_EVENT_MASK
242:                                                        | AWTEvent.MOUSE_MOTION_EVENT_MASK);
243:                                return null;
244:                            }
245:                        });
246:            }
247:
248:            private void stopListeningForOtherDrags() {
249:                java.security.AccessController
250:                        .doPrivileged(new java.security.PrivilegedAction() {
251:                            public Object run() {
252:                                nativeContainer.getToolkit()
253:                                        .removeAWTEventListener(
254:                                                LightweightDispatcher.this );
255:                                return null;
256:                            }
257:                        });
258:                // removed any queued up dragged-over events
259:                Toolkit.getEventQueue().removeEvents(MouseEvent.class,
260:                        LWD_MOUSE_DRAGGED_OVER);
261:            }
262:
263:            /*
264:             * (Implementation of AWTEventListener)
265:             * Listen for drag events posted in other hw components so we can
266:             * track enter/exit regardless of where a drag originated
267:             */
268:            public void eventDispatched(AWTEvent e) {
269:                boolean isForeignDrag = (e instanceof  MouseEvent)
270:                        && (e.id == MouseEvent.MOUSE_DRAGGED)
271:                        && (e.getSource() != nativeContainer);
272:                if (!isForeignDrag) {
273:                    // only interested in drags from other hw components
274:                    return;
275:                }
276:                // execute trackMouseEnterExit on EventDispatchThread
277:                Toolkit.getEventQueue()
278:                        .postEvent(
279:                                new TrackEnterExitEvent(nativeContainer,
280:                                        (MouseEvent) e));
281:            }
282:
283:            /*
284:             * ActiveEvent that calls trackMouseEnterExit as a result of a drag
285:             * originating in a 'foreign' hw container. Normally, we'd only be
286:             * able to track mouse events in our own hw container.
287:             */
288:            private class TrackEnterExitEvent extends AWTEvent implements 
289:                    ActiveEvent {
290:                MouseEvent srcEvent;
291:
292:                public TrackEnterExitEvent(Component trackSrc, MouseEvent e) {
293:                    super (trackSrc, 0);
294:                    srcEvent = e;
295:                }
296:
297:                public void dispatch() {
298:                    MouseEvent me;
299:                    synchronized (nativeContainer.getTreeLock()) {
300:                        Component srcComponent = srcEvent.getComponent();
301:                        // component may have disappeared since drag event posted
302:                        // (i.e. Swing hierarchical menus)
303:                        if (!srcComponent.isShowing()
304:                                || !nativeContainer.isShowing()) {
305:                            return;
306:                        }
307:                        //
308:                        // create an internal 'dragged-over' event indicating
309:                        // we are being dragged over from another hw component
310:                        //
311:                        me = new MouseEvent(nativeContainer,
312:                                LWD_MOUSE_DRAGGED_OVER, srcEvent.getWhen(),
313:                                srcEvent.getModifiers(), srcEvent.getX(),
314:                                srcEvent.getY(), srcEvent.getClickCount(),
315:                                srcEvent.isPopupTrigger());
316:                        // translate coordinates to this native container
317:                        Point ptSrcOrigin = srcComponent.getLocationOnScreen();
318:                        Point ptDstOrigin = nativeContainer
319:                                .getLocationOnScreen();
320:                        me.translatePoint(ptSrcOrigin.x - ptDstOrigin.x,
321:                                ptSrcOrigin.y - ptDstOrigin.y);
322:                    }
323:                    //System.out.println("Track event: " + me);
324:                    // feed the 'dragged-over' event directly to the enter/exit
325:                    // code (not a real event so don't pass it to dispatchEvent)
326:                    Component targetOver = nativeContainer.getMouseEventTarget(
327:                            me.getX(), me.getY(), true);
328:                    trackMouseEnterExit(targetOver, me);
329:                }
330:            }
331:
332:            /**
333:             * Sends a mouse event to the current mouse event recipient using
334:             * the given event (sent to the windowed host) as a srcEvent.  If
335:             * the mouse event target is still in the component tree, the
336:             * coordinates of the event are translated to those of the target.
337:             * If the target has been removed, we don't bother to send the
338:             * message.
339:             */
340:            void retargetMouseEvent(Component target, int id, MouseEvent e) {
341:                if (target == null) {
342:                    return; // mouse is over another hw component
343:                }
344:                int x = e.getX(), y = e.getY();
345:                Component component;
346:                for (component = target; component != null
347:                        && component != nativeContainer; component = component
348:                        .getParent()) {
349:                    x -= component.x;
350:                    y -= component.y;
351:                }
352:                if (component != null) {
353:                    MouseEvent retargeted = new MouseEvent(target, id, e
354:                            .getWhen(), e.getModifiers(), x, y, e
355:                            .getClickCount(), e.isPopupTrigger());
356:                    if (target == nativeContainer) {
357:                        // avoid recursively calling LightweightDispatcher...
358:                        ((Container) target).dispatchEventToSelf(retargeted);
359:                    } else {
360:                        target.dispatchEvent(retargeted);
361:                    }
362:                }
363:            }
364:
365:            /**
366:             * Set the cursor for a lightweight component
367:             * Enforce that null cursor means inheriting from parent
368:             */
369:            void updateCursor(Component comp) {
370:                // if user wants to change the cursor, we do it even mouse is dragging
371:                // so LightweightDispatcher's dragging state is not checked here
372:                if (comp != cursorOn) {
373:                    return;
374:                }
375:
376:                if (comp == null) {
377:                    comp = nativeContainer;
378:                }
379:                Cursor cursor = comp.getCursor();
380:                while (cursor == null && comp != nativeContainer) {
381:                    comp = comp.getParent();
382:                    if (comp == null) {
383:                        cursor = nativeContainer.getCursor();
384:                        break;
385:                    }
386:                    cursor = comp.getCursor();
387:                }
388:                if (cursor != lightCursor) {
389:                    lightCursor = cursor;
390:                    // Only change the cursor on the peer, because we want client code to think
391:                    // that the Container's cursor only changes in response to setCursor calls.
392:                    ComponentPeer ncPeer = nativeContainer.peer;
393:                    if (ncPeer != null) {
394:                        ncPeer.setCursor(cursor);
395:                    }
396:                }
397:            }
398:
399:            /**
400:             * get the lightweight component mouse cursor is on
401:             * null means the nativeContainer
402:             */
403:            Component getCursorOn() {
404:                return cursorOn;
405:            }
406:
407:            // --- member variables -------------------------------
408:
409:            /**
410:             * The windowed container that might be hosting events for
411:             * lightweight components.
412:             */
413:            private Container nativeContainer;
414:            /**
415:             * The current lightweight component that has focus that is being
416:             * hosted by this container.  If this is a null reference then
417:             * there is currently no focus on a lightweight component being
418:             * hosted by this container
419:             */
420:            private Component focus;
421:            /**
422:             * The current lightweight component being hosted by this windowed
423:             * component that has mouse events being forwarded to it.  If this
424:             * is null, there are currently no mouse events being forwarded to
425:             * a lightweight component.
426:             */
427:            private transient Component mouseEventTarget;
428:            /**
429:             *  lightweight component the mouse cursor is on
430:             */
431:            private transient Component cursorOn;
432:            /**
433:             * The last component entered
434:             */
435:            private transient Component targetLastEntered;
436:            /**
437:             * Is the mouse over the native container
438:             */
439:            private transient boolean isMouseInNativeContainer = false;
440:            /**
441:             * Indicates if the mouse pointer is currently being dragged...
442:             * this is needed because we may receive exit events while dragging
443:             * and need to keep the current mouse target in this case.
444:             */
445:            private boolean dragging;
446:            /**
447:             * The cursor that is currently displayed for the lightwieght
448:             * components.  Remember this cursor, so we do not need to
449:             * change cursor on every mouse event.
450:             */
451:            private Cursor lightCursor;
452:            /**
453:             * The event mask for contained lightweight components.  Lightweight
454:             * components need a windowed container to host window-related
455:             * events.  This seperate mask indicates events that have been
456:             * requested by contained lightweight components without effecting
457:             * the mask of the windowed component itself.
458:             */
459:            private long eventMask;
460:            /**
461:             * The kind of events routed to lightweight components from windowed
462:             * hosts.
463:             */
464:            private static final long PROXY_EVENT_MASK = AWTEvent.FOCUS_EVENT_MASK
465:                    | AWTEvent.KEY_EVENT_MASK
466:                    | AWTEvent.MOUSE_EVENT_MASK
467:                    | AWTEvent.MOUSE_MOTION_EVENT_MASK;
468:            private static final long MOUSE_MASK = AWTEvent.MOUSE_EVENT_MASK
469:                    | AWTEvent.MOUSE_MOTION_EVENT_MASK;
470:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.