Source Code Cross Referenced for MenuSelectionManager.java in  » 6.0-JDK-Core » swing » javax » swing » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Home
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
26.ERP CRM Financial
27.ESB
28.Forum
29.Game
30.GIS
31.Graphic 3D
32.Graphic Library
33.Groupware
34.HTML Parser
35.IDE
36.IDE Eclipse
37.IDE Netbeans
38.Installer
39.Internationalization Localization
40.Inversion of Control
41.Issue Tracking
42.J2EE
43.J2ME
44.JBoss
45.JMS
46.JMX
47.Library
48.Mail Clients
49.Music
50.Net
51.Parser
52.PDF
53.Portal
54.Profiler
55.Project Management
56.Report
57.RSS RDF
58.Rule Engine
59.Science
60.Scripting
61.Search Engine
62.Security
63.Sevlet Container
64.Source Control
65.Swing Library
66.Template Engine
67.Test Coverage
68.Testing
69.UML
70.Web Crawler
71.Web Framework
72.Web Mail
73.Web Server
74.Web Services
75.Web Services apache cxf 2.2.6
76.Web Services AXIS2
77.Wiki Engine
78.Workflow Engines
79.XML
80.XML UI
Java Source Code / Java Documentation » 6.0 JDK Core » swing » javax.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001        /*
002         * Copyright 1997-2006 Sun Microsystems, Inc.  All Rights Reserved.
003         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004         *
005         * This code is free software; you can redistribute it and/or modify it
006         * under the terms of the GNU General Public License version 2 only, as
007         * published by the Free Software Foundation.  Sun designates this
008         * particular file as subject to the "Classpath" exception as provided
009         * by Sun in the LICENSE file that accompanied this code.
010         *
011         * This code is distributed in the hope that it will be useful, but WITHOUT
012         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014         * version 2 for more details (a copy is included in the LICENSE file that
015         * accompanied this code).
016         *
017         * You should have received a copy of the GNU General Public License version
018         * 2 along with this work; if not, write to the Free Software Foundation,
019         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020         *
021         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022         * CA 95054 USA or visit www.sun.com if you need additional information or
023         * have any questions.
024         */
025        package javax.swing;
026
027        import java.awt.*;
028        import java.util.*;
029        import java.awt.event.*;
030        import javax.swing.event.*;
031
032        import sun.awt.AppContext;
033
034        /**
035         * A MenuSelectionManager owns the selection in menu hierarchy.
036         * 
037         * @version 1.47 05/05/07
038         * @author Arnaud Weber
039         */
040        public class MenuSelectionManager {
041            private Vector selection = new Vector();
042
043            /* diagnostic aids -- should be false for production builds. */
044            private static final boolean TRACE = false; // trace creates and disposes
045            private static final boolean VERBOSE = false; // show reuse hits/misses
046            private static final boolean DEBUG = false; // show bad params, misc.
047
048            private static final StringBuilder MENU_SELECTION_MANAGER_KEY = new StringBuilder(
049                    "javax.swing.MenuSelectionManager");
050
051            /**
052             * Returns the default menu selection manager.
053             *
054             * @return a MenuSelectionManager object
055             */
056            public static MenuSelectionManager defaultManager() {
057                synchronized (MENU_SELECTION_MANAGER_KEY) {
058                    AppContext context = AppContext.getAppContext();
059                    MenuSelectionManager msm = (MenuSelectionManager) context
060                            .get(MENU_SELECTION_MANAGER_KEY);
061                    if (msm == null) {
062                        msm = new MenuSelectionManager();
063                        context.put(MENU_SELECTION_MANAGER_KEY, msm);
064                    }
065
066                    return msm;
067                }
068            }
069
070            /**
071             * Only one ChangeEvent is needed per button model instance since the
072             * event's only state is the source property.  The source of events
073             * generated is always "this".
074             */
075            protected transient ChangeEvent changeEvent = null;
076            protected EventListenerList listenerList = new EventListenerList();
077
078            /**
079             * Changes the selection in the menu hierarchy.  The elements
080             * in the array are sorted in order from the root menu
081             * element to the currently selected menu element.
082             * <p>
083             * Note that this method is public but is used by the look and
084             * feel engine and should not be called by client applications.
085             *
086             * @param path  an array of <code>MenuElement</code> objects specifying
087             *        the selected path
088             */
089            public void setSelectedPath(MenuElement[] path) {
090                int i, c;
091                int currentSelectionCount = selection.size();
092                int firstDifference = 0;
093
094                if (path == null) {
095                    path = new MenuElement[0];
096                }
097
098                if (DEBUG) {
099                    System.out.print("Previous:  ");
100                    printMenuElementArray(getSelectedPath());
101                    System.out.print("New:  ");
102                    printMenuElementArray(path);
103                }
104
105                for (i = 0, c = path.length; i < c; i++) {
106                    if (i < currentSelectionCount
107                            && (MenuElement) selection.elementAt(i) == path[i])
108                        firstDifference++;
109                    else
110                        break;
111                }
112
113                for (i = currentSelectionCount - 1; i >= firstDifference; i--) {
114                    MenuElement me = (MenuElement) selection.elementAt(i);
115                    selection.removeElementAt(i);
116                    me.menuSelectionChanged(false);
117                }
118
119                for (i = firstDifference, c = path.length; i < c; i++) {
120                    if (path[i] != null) {
121                        selection.addElement(path[i]);
122                        path[i].menuSelectionChanged(true);
123                    }
124                }
125
126                fireStateChanged();
127            }
128
129            /**
130             * Returns the path to the currently selected menu item
131             *
132             * @return an array of MenuElement objects representing the selected path
133             */
134            public MenuElement[] getSelectedPath() {
135                MenuElement res[] = new MenuElement[selection.size()];
136                int i, c;
137                for (i = 0, c = selection.size(); i < c; i++)
138                    res[i] = (MenuElement) selection.elementAt(i);
139                return res;
140            }
141
142            /**
143             * Tell the menu selection to close and unselect all the menu components. Call this method
144             * when a choice has been made
145             */
146            public void clearSelectedPath() {
147                if (selection.size() > 0) {
148                    setSelectedPath(null);
149                }
150            }
151
152            /**
153             * Adds a ChangeListener to the button.
154             *
155             * @param l the listener to add
156             */
157            public void addChangeListener(ChangeListener l) {
158                listenerList.add(ChangeListener.class, l);
159            }
160
161            /**
162             * Removes a ChangeListener from the button.
163             *
164             * @param l the listener to remove
165             */
166            public void removeChangeListener(ChangeListener l) {
167                listenerList.remove(ChangeListener.class, l);
168            }
169
170            /**
171             * Returns an array of all the <code>ChangeListener</code>s added
172             * to this MenuSelectionManager with addChangeListener().
173             *
174             * @return all of the <code>ChangeListener</code>s added or an empty
175             *         array if no listeners have been added
176             * @since 1.4
177             */
178            public ChangeListener[] getChangeListeners() {
179                return (ChangeListener[]) listenerList
180                        .getListeners(ChangeListener.class);
181            }
182
183            /**
184             * Notifies all listeners that have registered interest for
185             * notification on this event type.  The event instance 
186             * is created lazily.
187             *
188             * @see EventListenerList
189             */
190            protected void fireStateChanged() {
191                // Guaranteed to return a non-null array
192                Object[] listeners = listenerList.getListenerList();
193                // Process the listeners last to first, notifying
194                // those that are interested in this event
195                for (int i = listeners.length - 2; i >= 0; i -= 2) {
196                    if (listeners[i] == ChangeListener.class) {
197                        // Lazily create the event:
198                        if (changeEvent == null)
199                            changeEvent = new ChangeEvent(this );
200                        ((ChangeListener) listeners[i + 1])
201                                .stateChanged(changeEvent);
202                    }
203                }
204            }
205
206            /**
207             * When a MenuElement receives an event from a MouseListener, it should never process the event
208             * directly. Instead all MenuElements should call this method with the event.
209             *
210             * @param event  a MouseEvent object
211             */
212            public void processMouseEvent(MouseEvent event) {
213                int screenX, screenY;
214                Point p;
215                int i, c, j, d;
216                Component mc;
217                Rectangle r2;
218                int cWidth, cHeight;
219                MenuElement menuElement;
220                MenuElement subElements[];
221                MenuElement path[];
222                Vector tmp;
223                int selectionSize;
224                p = event.getPoint();
225
226                Component source = (Component) event.getSource();
227
228                if (!source.isShowing()) {
229                    // This can happen if a mouseReleased removes the
230                    // containing component -- bug 4146684
231                    return;
232                }
233
234                int type = event.getID();
235                int modifiers = event.getModifiers();
236                // 4188027: drag enter/exit added in JDK 1.1.7A, JDK1.2
237                if ((type == MouseEvent.MOUSE_ENTERED || type == MouseEvent.MOUSE_EXITED)
238                        && ((modifiers & (InputEvent.BUTTON1_MASK
239                                | InputEvent.BUTTON2_MASK | InputEvent.BUTTON3_MASK)) != 0)) {
240                    return;
241                }
242
243                SwingUtilities.convertPointToScreen(p, source);
244
245                screenX = p.x;
246                screenY = p.y;
247
248                tmp = (Vector) selection.clone();
249                selectionSize = tmp.size();
250                boolean success = false;
251                for (i = selectionSize - 1; i >= 0 && success == false; i--) {
252                    menuElement = (MenuElement) tmp.elementAt(i);
253                    subElements = menuElement.getSubElements();
254
255                    path = null;
256                    for (j = 0, d = subElements.length; j < d
257                            && success == false; j++) {
258                        if (subElements[j] == null)
259                            continue;
260                        mc = subElements[j].getComponent();
261                        if (!mc.isShowing())
262                            continue;
263                        if (mc instanceof  JComponent) {
264                            cWidth = ((JComponent) mc).getWidth();
265                            cHeight = ((JComponent) mc).getHeight();
266                        } else {
267                            r2 = mc.getBounds();
268                            cWidth = r2.width;
269                            cHeight = r2.height;
270                        }
271                        p.x = screenX;
272                        p.y = screenY;
273                        SwingUtilities.convertPointFromScreen(p, mc);
274
275                        /** Send the event to visible menu element if menu element currently in
276                         *  the selected path or contains the event location
277                         */
278                        if ((p.x >= 0 && p.x < cWidth && p.y >= 0 && p.y < cHeight)) {
279                            int k;
280                            if (path == null) {
281                                path = new MenuElement[i + 2];
282                                for (k = 0; k <= i; k++)
283                                    path[k] = (MenuElement) tmp.elementAt(k);
284                            }
285                            path[i + 1] = subElements[j];
286                            MenuElement currentSelection[] = getSelectedPath();
287
288                            // Enter/exit detection -- needs tuning...
289                            if (currentSelection[currentSelection.length - 1] != path[i + 1]
290                                    && (currentSelection.length < 2 || currentSelection[currentSelection.length - 2] != path[i + 1])) {
291                                Component oldMC = currentSelection[currentSelection.length - 1]
292                                        .getComponent();
293
294                                MouseEvent exitEvent = new MouseEvent(oldMC,
295                                        MouseEvent.MOUSE_EXITED, event
296                                                .getWhen(), event
297                                                .getModifiers(), p.x, p.y,
298                                        event.getXOnScreen(), event
299                                                .getYOnScreen(), event
300                                                .getClickCount(), event
301                                                .isPopupTrigger(),
302                                        MouseEvent.NOBUTTON);
303                                currentSelection[currentSelection.length - 1]
304                                        .processMouseEvent(exitEvent, path,
305                                                this );
306
307                                MouseEvent enterEvent = new MouseEvent(mc,
308                                        MouseEvent.MOUSE_ENTERED, event
309                                                .getWhen(), event
310                                                .getModifiers(), p.x, p.y,
311                                        event.getXOnScreen(), event
312                                                .getYOnScreen(), event
313                                                .getClickCount(), event
314                                                .isPopupTrigger(),
315                                        MouseEvent.NOBUTTON);
316                                subElements[j].processMouseEvent(enterEvent,
317                                        path, this );
318                            }
319                            MouseEvent mouseEvent = new MouseEvent(mc, event
320                                    .getID(), event.getWhen(), event
321                                    .getModifiers(), p.x, p.y, event
322                                    .getXOnScreen(), event.getYOnScreen(),
323                                    event.getClickCount(), event
324                                            .isPopupTrigger(),
325                                    MouseEvent.NOBUTTON);
326                            subElements[j].processMouseEvent(mouseEvent, path,
327                                    this );
328                            success = true;
329                            event.consume();
330                        }
331                    }
332                }
333            }
334
335            private void printMenuElementArray(MenuElement path[]) {
336                printMenuElementArray(path, false);
337            }
338
339            private void printMenuElementArray(MenuElement path[],
340                    boolean dumpStack) {
341                System.out.println("Path is(");
342                int i, j;
343                for (i = 0, j = path.length; i < j; i++) {
344                    for (int k = 0; k <= i; k++)
345                        System.out.print("  ");
346                    MenuElement me = (MenuElement) path[i];
347                    if (me instanceof  JMenuItem) {
348                        System.out.println(((JMenuItem) me).getText() + ", ");
349                    } else if (me instanceof  JMenuBar) {
350                        System.out.println("JMenuBar, ");
351                    } else if (me instanceof  JPopupMenu) {
352                        System.out.println("JPopupMenu, ");
353                    } else if (me == null) {
354                        System.out.println("NULL , ");
355                    } else {
356                        System.out.println("" + me + ", ");
357                    }
358                }
359                System.out.println(")");
360
361                if (dumpStack == true)
362                    Thread.dumpStack();
363            }
364
365            /**
366             * Returns the component in the currently selected path 
367             * which contains sourcePoint.
368             *
369             * @param source The component in whose coordinate space sourcePoint
370             *        is given
371             * @param sourcePoint The point which is being tested
372             * @return The component in the currently selected path which
373             *         contains sourcePoint (relative to the source component's 
374             *         coordinate space.  If sourcePoint is not inside a component
375             *         on the currently selected path, null is returned.
376             */
377            public Component componentForPoint(Component source,
378                    Point sourcePoint) {
379                int screenX, screenY;
380                Point p = sourcePoint;
381                int i, c, j, d;
382                Component mc;
383                Rectangle r2;
384                int cWidth, cHeight;
385                MenuElement menuElement;
386                MenuElement subElements[];
387                Vector tmp;
388                int selectionSize;
389
390                SwingUtilities.convertPointToScreen(p, source);
391
392                screenX = p.x;
393                screenY = p.y;
394
395                tmp = (Vector) selection.clone();
396                selectionSize = tmp.size();
397                for (i = selectionSize - 1; i >= 0; i--) {
398                    menuElement = (MenuElement) tmp.elementAt(i);
399                    subElements = menuElement.getSubElements();
400
401                    for (j = 0, d = subElements.length; j < d; j++) {
402                        if (subElements[j] == null)
403                            continue;
404                        mc = subElements[j].getComponent();
405                        if (!mc.isShowing())
406                            continue;
407                        if (mc instanceof  JComponent) {
408                            cWidth = ((JComponent) mc).getWidth();
409                            cHeight = ((JComponent) mc).getHeight();
410                        } else {
411                            r2 = mc.getBounds();
412                            cWidth = r2.width;
413                            cHeight = r2.height;
414                        }
415                        p.x = screenX;
416                        p.y = screenY;
417                        SwingUtilities.convertPointFromScreen(p, mc);
418
419                        /** Return the deepest component on the selection
420                         *  path in whose bounds the event's point occurs
421                         */
422                        if (p.x >= 0 && p.x < cWidth && p.y >= 0
423                                && p.y < cHeight) {
424                            return mc;
425                        }
426                    }
427                }
428                return null;
429            }
430
431            /**
432             * When a MenuElement receives an event from a KeyListener, it should never process the event
433             * directly. Instead all MenuElements should call this method with the event.
434             *
435             * @param e  a KeyEvent object
436             */
437            public void processKeyEvent(KeyEvent e) {
438                MenuElement[] sel2 = new MenuElement[0];
439                sel2 = (MenuElement[]) selection.toArray(sel2);
440                int selSize = sel2.length;
441                MenuElement[] path;
442
443                if (selSize < 1) {
444                    return;
445                }
446
447                for (int i = selSize - 1; i >= 0; i--) {
448                    MenuElement elem = sel2[i];
449                    MenuElement[] subs = elem.getSubElements();
450                    path = null;
451
452                    for (int j = 0; j < subs.length; j++) {
453                        if (subs[j] == null
454                                || !subs[j].getComponent().isShowing()
455                                || !subs[j].getComponent().isEnabled()) {
456                            continue;
457                        }
458
459                        if (path == null) {
460                            path = new MenuElement[i + 2];
461                            System.arraycopy(sel2, 0, path, 0, i + 1);
462                        }
463                        path[i + 1] = subs[j];
464                        subs[j].processKeyEvent(e, path, this );
465                        if (e.isConsumed()) {
466                            return;
467                        }
468                    }
469                }
470
471                // finally dispatch event to the first component in path
472                path = new MenuElement[1];
473                path[0] = sel2[0];
474                path[0].processKeyEvent(e, path, this );
475                if (e.isConsumed()) {
476                    return;
477                }
478            }
479
480            /** 
481             * Return true if c is part of the currently used menu
482             */
483            public boolean isComponentPartOfCurrentMenu(Component c) {
484                if (selection.size() > 0) {
485                    MenuElement me = (MenuElement) selection.elementAt(0);
486                    return isComponentPartOfCurrentMenu(me, c);
487                } else
488                    return false;
489            }
490
491            private boolean isComponentPartOfCurrentMenu(MenuElement root,
492                    Component c) {
493                MenuElement children[];
494                int i, d;
495
496                if (root == null)
497                    return false;
498
499                if (root.getComponent() == c)
500                    return true;
501                else {
502                    children = root.getSubElements();
503                    for (i = 0, d = children.length; i < d; i++) {
504                        if (isComponentPartOfCurrentMenu(children[i], c))
505                            return true;
506                    }
507                }
508                return false;
509            }
510        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.