Source Code Cross Referenced for JideMenu.java in  » Swing-Library » jide-common » com » jidesoft » swing » 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 » Swing Library » jide common » com.jidesoft.swing 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * @(#)JideMenu.java
003:         *
004:         * Copyright 2002 - 2004 JIDE Software Inc. All rights reserved.
005:         */
006:        package com.jidesoft.swing;
007:
008:        import com.jidesoft.plaf.UIDefaultsLookup;
009:
010:        import javax.swing.*;
011:        import javax.swing.event.MenuEvent;
012:        import javax.swing.event.MenuListener;
013:        import java.awt.*;
014:        import java.awt.event.ActionEvent;
015:        import java.awt.event.ActionListener;
016:
017:        /**
018:         * A special implementation of JMenu. It is used to replace JMenu in order to use with CommandBar.
019:         * <br>
020:         * It has two special features.
021:         * First, it has a PopupMenuCustomizer for lazy menu creation. Instead of creating menu upfront which might be
022:         * quite expensive, you can create it using PopupMenuCustomizer. PopupMenuCustomizer is called before
023:         * the menu is set visible. Please note, when you use PopupMenuCustomizer, you need to remove the old menu items you added previously using
024:         * PopupMenuCustomizer. Otherwise, you will see a menu which gets longer and longer when you show it. See below for an example.
025:         * <code><pre>
026:         * JideMenu jideMenu = new JideMenu("Dynamic");
027:         * jideMenu.setPopupMenuCustomizer(new JideMenu.PopupMenuCustomizer(){
028:         *     public void customize(JPopupMenu menu) {
029:         *         menu.add("item 1");
030:         *         menu.add("item 2");
031:         *         menu.add("item 3");
032:         *         menu.add("item 4");
033:         *         menu.add("item 5");
034:         *     }
035:         * });
036:         * </pre></code>
037:         * <p/>
038:         * Second feature is popup alignment. Usually menu and its popup align to the left side. In our case, we hope
039:         * they align to right side. So we added a method call setPreferredPopupHorizontalAlignment(). You can set
040:         * to RIGHT if you want to.
041:         * <p/>
042:         */
043:        public class JideMenu extends JMenu implements  Alignable {
044:
045:            private int _preferredPopupHorizontalAlignment = LEFT;
046:
047:            private int _preferredPopupVerticalAlignment = BOTTOM;
048:
049:            private MenuCreator _menuCreator;
050:
051:            private PopupMenuCustomizer _customizer;
052:
053:            public static int DELAY = 400;
054:
055:            private int _orientation;
056:
057:            public JideMenu() {
058:                initMenu();
059:            }
060:
061:            public JideMenu(String s) {
062:                super (s);
063:                initMenu();
064:            }
065:
066:            public JideMenu(Action a) {
067:                super (a);
068:                initMenu();
069:            }
070:
071:            public JideMenu(String s, boolean b) {
072:                super (s, b);
073:                initMenu();
074:            }
075:
076:            protected void initMenu() {
077:                //        setDelay(DELAY);
078:                addMenuListener(new MenuListener() {
079:                    public void menuSelected(MenuEvent e) {
080:                        MenuCreator menuCreator;
081:                        if ((menuCreator = getMenuCreator()) != null) {
082:                            menuCreator.createMenu();
083:                            if (getPopupMenu().getComponentCount() == 0) {
084:                                return;
085:                            }
086:                        }
087:
088:                        PopupMenuCustomizer customizer;
089:                        if ((customizer = getPopupMenuCustomizer()) != null) {
090:                            customizer.customize(getPopupMenu());
091:                            if (getPopupMenu().getComponentCount() == 0) {
092:                                return;
093:                            }
094:                        }
095:                    }
096:
097:                    public void menuDeselected(MenuEvent e) {
098:                    }
099:
100:                    public void menuCanceled(MenuEvent e) {
101:                    }
102:                });
103:            }
104:
105:            /**
106:             * Checks if the menu is added to a top level menu container. It will be consider as top level menu when
107:             * <br> 1. getParent() equals null, or
108:             * <br> 2. getParent() is not an instance of JPopupMenu
109:             * <br> Please note, the definition of topLevelMenu is different from that of JMenu.
110:             *
111:             * @return true if it's top level menu.
112:             */
113:            @Override
114:            public boolean isTopLevelMenu() {
115:                return getParent() == null
116:                        || !(getParent() instanceof  JPopupMenu);//TopLevelMenuContainer || getParent() instanceof JMenuBar;
117:            }
118:
119:            /**
120:             * @deprecated The createMenu method of MenuCreator should JPopupMenu as parameter. Since it's a public API
121:             *             we have to deprecated this one and ask users to use {@link PopupMenuCustomizer} instead.
122:             */
123:            public interface MenuCreator {
124:                void createMenu();
125:            }
126:
127:            /**
128:             * Customizes the popup menu. This method will be called every time before popup menu is set visible.
129:             */
130:            public interface PopupMenuCustomizer {
131:                void customize(JPopupMenu menu);
132:            }
133:
134:            /**
135:             * Gets the MenuCreator.
136:             *
137:             * @return the MenuCreator.
138:             * @deprecated use{@link PopupMenuCustomizer} and {@link #getPopupMenuCustomizer()} instead.
139:             */
140:            public MenuCreator getMenuCreator() {
141:                return _menuCreator;
142:            }
143:
144:            /**
145:             * Sets the MenuCreator. MenuCreator can be used to do lazy menu creation. If you put code
146:             * in the MenuCreator, it won't be called until before the menu is set visible.
147:             *
148:             * @param menuCreator
149:             * @deprecated use{@link PopupMenuCustomizer} and {@link #setPopupMenuCustomizer(com.jidesoft.swing.JideMenu.PopupMenuCustomizer)} instead.
150:             */
151:            public void setMenuCreator(MenuCreator menuCreator) {
152:                _menuCreator = menuCreator;
153:            }
154:
155:            /**
156:             * Gets the PopupMenuCustomizer.
157:             *
158:             * @return the PopupMenuCustomizer.
159:             */
160:            public PopupMenuCustomizer getPopupMenuCustomizer() {
161:                return _customizer;
162:            }
163:
164:            /**
165:             * Sets the PopupMenuCustomizer. PopupMenuCustomizer can be used to do lazy menu creation. If you put code
166:             * in the MenuCreator, it won't be called until before the menu is set visible.
167:             * <p/>
168:             * PopupMenuCustomizer has a customize method. The popup menu of this menu will be passed in.
169:             * You can add/remove/change the menu items in customize method. For example, instead of
170:             * <code><pre>
171:             * JideMenu menu = new JideMenu();
172:             * menu.add(new JMenuItem("..."));
173:             * menu.add(new JMenuItem("..."));
174:             * </pre></code>
175:             * You can do
176:             * <code><pre>
177:             * JideMenu menu = new JideMenu();
178:             * menu.setPopupMenuCustomzier(new JideMenu.PopupMenuCustomizer() {
179:             *     void customize(JPopupMenu popupMenu) {
180:             *         poupMenu.removeAll();
181:             *         popupMenu.add(new JMenuItem("..."));
182:             *         popupMenu.add(new JMenuItem("..."));
183:             *     }
184:             * }
185:             * </pre></code>
186:             * If the menu is never used, the two add methods will never be called thus improve the performance.
187:             *
188:             * @param customizer
189:             */
190:            public void setPopupMenuCustomizer(PopupMenuCustomizer customizer) {
191:                _customizer = customizer;
192:            }
193:
194:            @Override
195:            protected Point getPopupMenuOrigin() {
196:                int x = 0;
197:                int y = 0;
198:                JPopupMenu pm = getPopupMenu();
199:
200:                // Figure out the sizes needed to caclulate the menu position
201:                Dimension s = getSize();
202:                Dimension pmSize = pm.getPreferredSize();
203:
204:                Point position = getLocationOnScreen();
205:                Toolkit toolkit = Toolkit.getDefaultToolkit();
206:                GraphicsConfiguration gc = getGraphicsConfiguration();
207:                Rectangle screenBounds = new Rectangle(toolkit.getScreenSize());
208:                GraphicsEnvironment ge = GraphicsEnvironment
209:                        .getLocalGraphicsEnvironment();
210:                GraphicsDevice[] gd = ge.getScreenDevices();
211:                for (int i = 0; i < gd.length; i++) {
212:                    if (gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) {
213:                        GraphicsConfiguration dgc = gd[i]
214:                                .getDefaultConfiguration();
215:                        if (dgc.getBounds().contains(position)) {
216:                            gc = dgc;
217:                            break;
218:                        }
219:                    }
220:                }
221:
222:                if (gc != null) {
223:                    screenBounds = gc.getBounds();
224:                    // take screen insets (e.g. taskbar) into account
225:                    Insets screenInsets = toolkit.getScreenInsets(gc);
226:
227:                    screenBounds.width -= Math.abs(screenInsets.left
228:                            + screenInsets.right);
229:                    screenBounds.height -= Math.abs(screenInsets.top
230:                            + screenInsets.bottom);
231:                    position.x -= Math.abs(screenInsets.left);
232:                    position.y -= Math.abs(screenInsets.top);
233:                }
234:
235:                Container parent = getParent();
236:                if (parent instanceof  JPopupMenu) {
237:                    // We are a submenu (pull-right)
238:                    int xOffset = UIDefaultsLookup
239:                            .getInt("Menu.submenuPopupOffsetX");
240:                    int yOffset = UIDefaultsLookup
241:                            .getInt("Menu.submenuPopupOffsetY");
242:
243:                    if (this .getComponentOrientation().isLeftToRight()) {
244:                        if (JideSwingUtilities.getOrientationOf(this ) == HORIZONTAL) {
245:                            // First determine x:
246:                            x = s.width + xOffset; // Prefer placement to the right
247:                            if (position.x + x + pmSize.width >= screenBounds.width
248:                                    + screenBounds.x
249:                                    &&
250:                                    // popup doesn't fit - place it wherever there's more room
251:                                    screenBounds.width - s.width < 2 * (position.x - screenBounds.x)) {
252:
253:                                x = 0 - xOffset - pmSize.width;
254:                            }
255:                        } else {
256:                            // First determine x:
257:                            x = s.width + xOffset; // Prefer placement to the right
258:                            if (position.x + x + pmSize.width >= screenBounds.width
259:                                    + screenBounds.x
260:                                    &&
261:                                    // popup doesn't fit - place it wherever there's more room
262:                                    screenBounds.width - s.width < 2 * (position.x - screenBounds.x)) {
263:
264:                                x = 0 - xOffset - pmSize.width;
265:                            }
266:                        }
267:                    } else {
268:                        // First determine x:
269:                        x = 0 - xOffset - pmSize.width; // Prefer placement to the left
270:                        if (position.x + x < screenBounds.x &&
271:                        // popup doesn't fit - place it wherever there's more room
272:                                screenBounds.width - s.width > 2 * (position.x - screenBounds.x)) {
273:
274:                            x = s.width + xOffset;
275:                        }
276:                    }
277:                    // Then the y:
278:                    y = yOffset; // Prefer dropping down
279:                    if (position.y + y + pmSize.height >= screenBounds.height
280:                            + screenBounds.y
281:                            &&
282:                            // popup doesn't fit - place it wherever there's more room
283:                            screenBounds.height - s.height < 2 * (position.y - screenBounds.y)) {
284:
285:                        y = s.height - yOffset - pmSize.height;
286:                    }
287:                } else {
288:                    // We are a toplevel menu (pull-down)
289:                    int xOffset = UIDefaultsLookup
290:                            .getInt("Menu.menuPopupOffsetX");
291:                    int yOffset = UIDefaultsLookup
292:                            .getInt("Menu.menuPopupOffsetY");
293:
294:                    if (this .getComponentOrientation().isLeftToRight()) {
295:                        if (JideSwingUtilities.getOrientationOf(this ) == HORIZONTAL) {
296:                            // First determine the x:
297:                            if (getPreferredPopupHorizontalAlignment() == LEFT) {
298:                                x = xOffset; // Extend to the right
299:                                if (position.x + x + pmSize.width >= screenBounds.width
300:                                        + screenBounds.x
301:                                        &&
302:                                        // popup doesn't fit - place it wherever there's more room
303:                                        screenBounds.width - s.width < 2 * (position.x - screenBounds.x)) {
304:
305:                                    x = s.width - xOffset - pmSize.width;
306:                                }
307:                            } else {
308:                                x = -pmSize.width + xOffset + s.width; // align right
309:                                if (position.x + x < screenBounds.x) {
310:                                    x = screenBounds.x - position.x;
311:                                }
312:                            }
313:                        } else {
314:                            // First determine the x:
315:                            x = -xOffset - pmSize.width; // Extend to the left
316:                            if (position.x + x < screenBounds.x &&
317:                            // popup doesn't fit - place it wherever there's more room
318:                                    screenBounds.width - s.width > 2 * (position.x - screenBounds.x)) {
319:
320:                                x = s.width + xOffset;
321:                            }
322:                        }
323:                    } else {
324:                        // TODO: when RTL - consider vertical case
325:                        // First determine the x:
326:                        x = s.width - xOffset - pmSize.width; // Extend to the left
327:                        if (position.x + x < screenBounds.x &&
328:                        // popup doesn't fit - place it wherever there's more room
329:                                screenBounds.width - s.width > 2 * (position.x - screenBounds.x)) {
330:
331:                            x = xOffset;
332:                        }
333:                    }
334:
335:                    // Then the y:
336:                    if (JideSwingUtilities.getOrientationOf(this ) == HORIZONTAL) {
337:                        y = s.height + yOffset; // Prefer dropping down
338:                        if (position.y + y + pmSize.height >= screenBounds.height
339:                                &&
340:                                // popup doesn't fit - place it wherever there's more room
341:                                screenBounds.height - s.height < 2 * (position.y - screenBounds.y)) {
342:
343:                            y = 0 - yOffset - pmSize.height; // Otherwise drop 'up'
344:                        }
345:                    } else {
346:                        y = -yOffset; // Prefer dropping up
347:                        if (position.y + y + pmSize.height >= screenBounds.height
348:                                &&
349:                                // popup doesn't fit - place it wherever there's more room
350:                                screenBounds.height - s.height < 2 * (position.y - screenBounds.y)) {
351:
352:                            y = 0 - yOffset - pmSize.height; // Otherwise drop 'up'
353:                        }
354:                    }
355:                }
356:
357:                return new Point(x, y);
358:            }
359:
360:            /**
361:             * Checks if the
362:             *
363:             * @return false if it's top leve menu. Otherwise, it will return what super.isOpaque().
364:             */
365:            @Override
366:            public boolean isOpaque() {
367:                if (isTopLevelMenu()) { // make top level menu opaque
368:                    return false;
369:                } else {
370:                    return super .isOpaque();
371:                }
372:            }
373:
374:            public boolean originalIsOpaque() {
375:                return super .isOpaque();
376:            }
377:
378:            protected void hideMenu() {
379:                MenuSelectionManager msm = MenuSelectionManager
380:                        .defaultManager();
381:                msm.clearSelectedPath();
382:            }
383:
384:            public int getPreferredPopupHorizontalAlignment() {
385:                return _preferredPopupHorizontalAlignment;
386:            }
387:
388:            public void setPreferredPopupHorizontalAlignment(
389:                    int preferredPopupHorizontalAlignment) {
390:                _preferredPopupHorizontalAlignment = preferredPopupHorizontalAlignment;
391:            }
392:
393:            public int getPreferredPopupVerticalAlignment() {
394:                return _preferredPopupVerticalAlignment;
395:            }
396:
397:            public void setPreferredPopupVerticalAlignment(
398:                    int preferredPopupVerticalAlignment) {
399:                _preferredPopupVerticalAlignment = preferredPopupVerticalAlignment;
400:            }
401:
402:            public boolean supportVerticalOrientation() {
403:                return true;
404:            }
405:
406:            public boolean supportHorizontalOrientation() {
407:                return true;
408:            }
409:
410:            public void setOrientation(int orientation) {
411:                int old = _orientation;
412:                if (old != orientation) {
413:                    _orientation = orientation;
414:                    firePropertyChange(PROPERTY_ORIENTATION, old, orientation);
415:                }
416:            }
417:
418:            public int getOrientation() {
419:                return _orientation;
420:            }
421:
422:            private static JideMenu _pendingMenu;
423:
424:            private static HideTimer _timer;
425:
426:            // use this flag to disable the hide timer as there are quite a few bugs on it that we don't know how to solve.
427:            private final static boolean DISABLE_TIMER = true;
428:
429:            @Override
430:            public void setPopupMenuVisible(boolean b) {
431:                if (b && getPopupMenu().getComponentCount() == 0) {
432:                    return;
433:                }
434:
435:                if (!DISABLE_TIMER) {
436:                    if (isTopLevelMenu()) {
437:                        setPopupMenuVisibleImmediately(b);
438:                    } else {
439:                        if (b) {
440:                            //                    System.out.println("show new menu");
441:                            stopTimer();
442:                            setPopupMenuVisibleImmediately(b);
443:                        } else {
444:                            // HACK: check if the calling stack has clearSelectedPath method.
445:                            StackTraceElement[] stackTraceElements = new Throwable()
446:                                    .getStackTrace();
447:                            for (int i = 0; i < stackTraceElements.length; i++) {
448:                                StackTraceElement stackTraceElement = stackTraceElements[i];
449:                                if (stackTraceElement.getMethodName().equals(
450:                                        "clearSelectedPath")) {
451:                                    setPopupMenuVisibleImmediately(b);
452:                                    return;
453:                                }
454:                            }
455:                            startTimer();
456:                        }
457:                    }
458:                } else {
459:                    setPopupMenuVisibleImmediately(b);
460:                }
461:            }
462:
463:            void setPopupMenuVisibleImmediately(boolean b) {
464:                super .setPopupMenuVisible(b);
465:            }
466:
467:            private class HideTimer extends Timer implements  ActionListener {
468:                public HideTimer() {
469:                    super (DELAY + 300, null);
470:                    addActionListener(this );
471:                    setRepeats(false);
472:                }
473:
474:                public void actionPerformed(ActionEvent e) {
475:                    stopTimer();
476:                }
477:            }
478:
479:            private void startTimer() {
480:                //        System.out.println("timer started");
481:                if (_timer != null) {
482:                    stopTimer();
483:                }
484:                _pendingMenu = this ;
485:                _timer = new HideTimer();
486:                _timer.start();
487:            }
488:
489:            private void stopTimer() {
490:                if (_timer != null) {
491:                    //            System.out.println("timer stopped");
492:                    if (_pendingMenu != null) {
493:                        //                System.out.println("hidding pending menu");
494:                        _pendingMenu.setPopupMenuVisibleImmediately(false);
495:                        _pendingMenu = null;
496:                    }
497:                    _timer.stop();
498:                    _timer = null;
499:                }
500:            }
501:
502:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.