GNU Classpath (0.95) | |
Frames | No Frames |
1: /* JPopupMenu.java -- 2: Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package javax.swing; 40: 41: import java.awt.Component; 42: import java.awt.Dimension; 43: import java.awt.Insets; 44: import java.awt.Point; 45: import java.awt.event.KeyEvent; 46: import java.awt.event.MouseEvent; 47: import java.beans.PropertyChangeEvent; 48: import java.beans.PropertyChangeListener; 49: import java.util.ArrayList; 50: import java.util.EventListener; 51: 52: import javax.accessibility.Accessible; 53: import javax.accessibility.AccessibleContext; 54: import javax.accessibility.AccessibleRole; 55: import javax.swing.event.MenuKeyListener; 56: import javax.swing.event.PopupMenuEvent; 57: import javax.swing.event.PopupMenuListener; 58: import javax.swing.plaf.PopupMenuUI; 59: 60: /** 61: * JPopupMenu is a container that is used to display popup menu's menu 62: * items. By default JPopupMenu is a lightweight container, however if it 63: * is the case that JPopupMenu's bounds are outside of main window, then 64: * heawyweight container will be used to display menu items. It is also 65: * possible to change JPopupMenu's default behavior and set JPopupMenu 66: * to always use heavyweight container. 67: * 68: * JPopupMenu can be displayed anywhere; it is a floating free popup menu. 69: * However before JPopupMenu is diplayed, its invoker property should be set. 70: * JPopupMenu's invoker is a component relative to which popup menu is 71: * displayed. 72: * 73: * JPopupMenu fires PopupMenuEvents to its registered listeners. Whenever 74: * JPopupMenu becomes visible on the screen then PopupMenuEvent indicating 75: * that popup menu became visible will be fired. In the case when 76: * JPopupMenu becomes invisible or cancelled without selection, then 77: * popupMenuBecomeInvisible() or popupMenuCancelled() methods of 78: * PopupMenuListeners will be invoked. 79: * 80: * JPopupMenu also fires PropertyChangeEvents when its bound properties 81: * change.In addittion to inheritted bound properties, JPopupMenu has 82: * 'visible' bound property. When JPopupMenu becomes visible/invisible on 83: * the screen it fires PropertyChangeEvents to its registered 84: * PropertyChangeListeners. 85: */ 86: public class JPopupMenu extends JComponent implements Accessible, MenuElement 87: { 88: private static final long serialVersionUID = -8336996630009646009L; 89: 90: /* indicates if popup's menu border should be painted*/ 91: private boolean borderPainted = true; 92: 93: /** Flag indicating whether lightweight, mediumweight or heavyweight popup 94: is used to display menu items. 95: 96: These are the possible cases: 97: 98: 1. if DefaultLightWeightPopupEnabled true 99: (i) use lightweight container if popup feets inside top-level window 100: (ii) only use heavyweight container (JDialog) if popup doesn't fit. 101: 102: 2. if DefaultLightWeightPopupEnabled false 103: (i) if popup fits, use awt.Panel (mediumWeight) 104: (ii) if popup doesn't fit, use JDialog (heavyWeight) 105: */ 106: private static boolean DefaultLightWeightPopupEnabled = true; 107: 108: /* Component that invokes popup menu. */ 109: transient Component invoker; 110: 111: /* Label for this popup menu. It is not used in most of the look and feel themes. */ 112: private String label; 113: 114: /*Amount of space between menuItem's in JPopupMenu and JPopupMenu's border */ 115: private Insets margin; 116: 117: /** Indicates whether ligthWeight container can be used to display popup 118: menu. This flag is the same as DefaultLightWeightPopupEnabled, but setting 119: this flag can change popup menu after creation of the object */ 120: private boolean lightWeightPopupEnabled; 121: 122: /** SelectionModel that keeps track of menu selection. */ 123: protected SingleSelectionModel selectionModel; 124: 125: /* Popup that is used to display JPopupMenu */ 126: private transient Popup popup; 127: 128: /** 129: * Location of the popup, X coordinate. 130: */ 131: private int popupLocationX; 132: 133: /** 134: * Location of the popup, Y coordinate. 135: */ 136: private int popupLocationY; 137: 138: /* Field indicating if popup menu is visible or not */ 139: private boolean visible = false; 140: 141: /** 142: * Creates a new JPopupMenu object. 143: */ 144: public JPopupMenu() 145: { 146: this(null); 147: } 148: 149: /** 150: * Creates a new JPopupMenu with specified label 151: * 152: * @param label Label for popup menu. 153: */ 154: public JPopupMenu(String label) 155: { 156: lightWeightPopupEnabled = getDefaultLightWeightPopupEnabled(); 157: setLabel(label); 158: setSelectionModel(new DefaultSingleSelectionModel()); 159: super.setVisible(false); 160: updateUI(); 161: } 162: 163: /** 164: * Adds given menu item to the popup menu 165: * 166: * @param item menu item to add to the popup menu 167: * 168: * @return menu item that was added to the popup menu 169: */ 170: public JMenuItem add(JMenuItem item) 171: { 172: this.insert(item, -1); 173: return item; 174: } 175: 176: /** 177: * Constructs menu item with a specified label and adds it to 178: * popup menu 179: * 180: * @param text label for the menu item to be added 181: * 182: * @return constructed menu item that was added to the popup menu 183: */ 184: public JMenuItem add(String text) 185: { 186: JMenuItem item = new JMenuItem(text); 187: return add(item); 188: } 189: 190: /** 191: * Constructs menu item associated with the specified action 192: * and adds it to the popup menu 193: * 194: * @param action Action for the new menu item 195: * 196: * @return menu item that was added to the menu 197: */ 198: public JMenuItem add(Action action) 199: { 200: JMenuItem item = createActionComponent(action); 201: 202: if (action != null) 203: action.addPropertyChangeListener(createActionChangeListener(item)); 204: 205: return add(item); 206: } 207: 208: /** 209: * Revomes component at the given index from the menu. 210: * 211: * @param index index of the component that will be removed in the menu 212: */ 213: public void remove(int index) 214: { 215: super.remove(index); 216: revalidate(); 217: } 218: 219: /** 220: * Create menu item associated with the given action 221: * and inserts it into the popup menu at the specified index 222: * 223: * @param action Action for the new menu item 224: * @param index index in the popup menu at which to insert new menu item. 225: */ 226: public void insert(Action action, int index) 227: { 228: JMenuItem item = new JMenuItem(action); 229: this.insert(item, index); 230: } 231: 232: /** 233: * Insert given component to the popup menu at the 234: * specified index 235: * 236: * @param component Component to insert 237: * @param index Index at which to insert given component 238: */ 239: public void insert(Component component, int index) 240: { 241: super.add(component, index); 242: } 243: 244: /** 245: * Returns flag indicating if newly created JPopupMenu will use 246: * heavyweight or lightweight container to display its menu items 247: * 248: * @return true if JPopupMenu will use lightweight container to display 249: * menu items by default, and false otherwise. 250: */ 251: public static boolean getDefaultLightWeightPopupEnabled() 252: { 253: return DefaultLightWeightPopupEnabled; 254: } 255: 256: /** 257: * Sets whether JPopupMenu should use ligthWeight container to 258: * display it menu items by default 259: * 260: * @param enabled true if JPopupMenu should use lightweight container 261: * for displaying its menu items, and false otherwise. 262: */ 263: public static void setDefaultLightWeightPopupEnabled(boolean enabled) 264: { 265: DefaultLightWeightPopupEnabled = enabled; 266: } 267: 268: /** 269: * This method returns the UI used to display the JPopupMenu. 270: * 271: * @return The UI used to display the JPopupMenu. 272: */ 273: public PopupMenuUI getUI() 274: { 275: return (PopupMenuUI) ui; 276: } 277: 278: /** 279: * Set the "UI" property of the menu item, which is a look and feel class 280: * responsible for handling popupMenu's input events and painting it. 281: * 282: * @param ui The new "UI" property 283: */ 284: public void setUI(PopupMenuUI ui) 285: { 286: super.setUI(ui); 287: } 288: 289: /** 290: * This method sets this menuItem's UI to the UIManager's default for the 291: * current look and feel. 292: */ 293: public void updateUI() 294: { 295: setUI((PopupMenuUI) UIManager.getUI(this)); 296: } 297: 298: /** 299: * This method returns a name to identify which look and feel class will be 300: * the UI delegate for the menuItem. 301: * 302: * @return The Look and Feel classID. "PopupMenuUI" 303: */ 304: public String getUIClassID() 305: { 306: return "PopupMenuUI"; 307: } 308: 309: /** 310: * Returns selectionModel used by this popup menu to keep 311: * track of the selection. 312: * 313: * @return popup menu's selection model 314: */ 315: public SingleSelectionModel getSelectionModel() 316: { 317: return selectionModel; 318: } 319: 320: /** 321: * Sets selection model for this popup menu 322: * 323: * @param model new selection model of this popup menu 324: */ 325: public void setSelectionModel(SingleSelectionModel model) 326: { 327: selectionModel = model; 328: } 329: 330: /** 331: * Creates new menu item associated with a given action. 332: * 333: * @param action Action used to create new menu item 334: * 335: * @return new created menu item associated with a given action. 336: */ 337: protected JMenuItem createActionComponent(Action action) 338: { 339: return new JMenuItem(action); 340: } 341: 342: /** 343: * Creates PropertyChangeListener that listens to PropertyChangeEvents 344: * occuring in the Action associated with given menu item in this popup menu. 345: * 346: * @param item MenuItem 347: * 348: * @return The PropertyChangeListener 349: */ 350: protected PropertyChangeListener createActionChangeListener(JMenuItem item) 351: { 352: return new ActionChangeListener(); 353: } 354: 355: /** 356: * Returns true if this popup menu will display its menu item in 357: * a lightweight container and false otherwise. 358: * 359: * @return true if this popup menu will display its menu items 360: * in a lightweight container and false otherwise. 361: */ 362: public boolean isLightWeightPopupEnabled() 363: { 364: return lightWeightPopupEnabled; 365: } 366: 367: /** 368: * DOCUMENT ME! 369: * 370: * @param enabled DOCUMENT ME! 371: */ 372: public void setLightWeightPopupEnabled(boolean enabled) 373: { 374: lightWeightPopupEnabled = enabled; 375: } 376: 377: /** 378: * Returns label for this popup menu 379: * 380: * @return label for this popup menu 381: */ 382: public String getLabel() 383: { 384: return label; 385: } 386: 387: /** 388: * Sets label for this popup menu. This method fires PropertyChangeEvent 389: * when the label property is changed. Please note that most 390: * of the Look & Feel will ignore this property. 391: * 392: * @param label label for this popup menu 393: */ 394: public void setLabel(String label) 395: { 396: if (label != this.label) 397: { 398: String oldLabel = this.label; 399: this.label = label; 400: firePropertyChange("label", oldLabel, label); 401: } 402: } 403: 404: /** 405: * Adds separator to this popup menu 406: */ 407: public void addSeparator() 408: { 409: // insert separator at the end of the list of menu items 410: this.insert(new Separator(), -1); 411: } 412: 413: /** 414: * Adds a MenuKeyListener to the popup. 415: * 416: * @param l - the listener to add. 417: */ 418: public void addMenuKeyListener(MenuKeyListener l) 419: { 420: listenerList.add(MenuKeyListener.class, l); 421: } 422: 423: /** 424: * Removes a MenuKeyListener from the popup. 425: * 426: * @param l - the listener to remove. 427: */ 428: public void removeMenuKeyListener(MenuKeyListener l) 429: { 430: listenerList.remove(MenuKeyListener.class, l); 431: } 432: 433: /** 434: * Returns array of getMenuKeyListeners that are listening to JPopupMenu. 435: * 436: * @return array of getMenuKeyListeners that are listening to JPopupMenu 437: */ 438: public MenuKeyListener[] getMenuKeyListeners() 439: { 440: return ((MenuKeyListener[]) listenerList.getListeners(MenuKeyListener.class)); 441: } 442: 443: /** 444: * Adds popupMenuListener to listen for PopupMenuEvents fired 445: * by the JPopupMenu 446: * 447: * @param listener PopupMenuListener to add to JPopupMenu 448: */ 449: public void addPopupMenuListener(PopupMenuListener listener) 450: { 451: listenerList.add(PopupMenuListener.class, listener); 452: } 453: 454: /** 455: * Removes PopupMenuListener from JPopupMenu's list of listeners 456: * 457: * @param listener PopupMenuListener which needs to be removed 458: */ 459: public void removePopupMenuListener(PopupMenuListener listener) 460: { 461: listenerList.remove(PopupMenuListener.class, listener); 462: } 463: 464: /** 465: * Returns array of PopupMenuListeners that are listening to JPopupMenu 466: * 467: * @return Array of PopupMenuListeners that are listening to JPopupMenu 468: */ 469: public PopupMenuListener[] getPopupMenuListeners() 470: { 471: return ((PopupMenuListener[]) listenerList.getListeners(PopupMenuListener.class)); 472: } 473: 474: /** 475: * This method calls popupMenuWillBecomeVisible() of popup menu's 476: * PopupMenuListeners. This method is invoked just before popup menu 477: * will appear on the screen. 478: */ 479: protected void firePopupMenuWillBecomeVisible() 480: { 481: EventListener[] ll = listenerList.getListeners(PopupMenuListener.class); 482: 483: for (int i = 0; i < ll.length; i++) 484: ((PopupMenuListener) ll[i]).popupMenuWillBecomeVisible(new PopupMenuEvent(this)); 485: } 486: 487: /** 488: * This method calls popupMenuWillBecomeInvisible() of popup 489: * menu's PopupMenuListeners. This method is invoked just before popup 490: * menu will disappear from the screen 491: */ 492: protected void firePopupMenuWillBecomeInvisible() 493: { 494: EventListener[] ll = listenerList.getListeners(PopupMenuListener.class); 495: 496: for (int i = 0; i < ll.length; i++) 497: ((PopupMenuListener) ll[i]).popupMenuWillBecomeInvisible(new PopupMenuEvent(this)); 498: } 499: 500: /** 501: * This method calls popupMenuCanceled() of popup menu's PopupMenuListeners. 502: * This method is invoked just before popup menu is cancelled. This happens 503: * when popup menu is closed without selecting any of its menu items. This 504: * usually happens when the top-level window is resized or moved. 505: */ 506: protected void firePopupMenuCanceled() 507: { 508: EventListener[] ll = listenerList.getListeners(PopupMenuListener.class); 509: 510: for (int i = 0; i < ll.length; i++) 511: ((PopupMenuListener) ll[i]).popupMenuCanceled(new PopupMenuEvent(this)); 512: } 513: 514: /** 515: * This methods sets popup menu's size to its' preferred size. If the 516: * popup menu's size is previously set it will be ignored. 517: */ 518: public void pack() 519: { 520: // Hook up this call so that it gets executed on the event thread in order 521: // to avoid synchronization problems when calling the layout manager. 522: if (! SwingUtilities.isEventDispatchThread()) 523: { 524: SwingUtilities.invokeLater(new Runnable() 525: { 526: public void run() 527: { 528: show(); 529: } 530: }); 531: } 532: 533: setSize(getPreferredSize()); 534: } 535: 536: /** 537: * Return visibility of the popup menu 538: * 539: * @return true if popup menu is visible on the screen and false otherwise. 540: */ 541: public boolean isVisible() 542: { 543: return visible; 544: } 545: 546: /** 547: * Sets visibility property of this popup menu. If the property is 548: * set to true then popup menu will be dispayed and popup menu will 549: * hide itself if visible property is set to false. 550: * 551: * @param visible true if popup menu will become visible and false otherwise. 552: */ 553: public void setVisible(final boolean visible) 554: { 555: // Hook up this call so that it gets executed on the event thread in order 556: // to avoid synchronization problems when calling the layout manager. 557: if (! SwingUtilities.isEventDispatchThread()) 558: { 559: SwingUtilities.invokeLater(new Runnable() 560: { 561: public void run() 562: { 563: setVisible(visible); 564: } 565: }); 566: } 567: 568: if (visible == isVisible()) 569: return; 570: 571: boolean old = isVisible(); 572: this.visible = visible; 573: if (old != isVisible()) 574: { 575: if (visible) 576: { 577: if (invoker != null && !(invoker instanceof JMenu)) 578: { 579: MenuElement[] menuEls; 580: if (getSubElements().length > 0) 581: { 582: menuEls = new MenuElement[2]; 583: menuEls[0] = this; 584: menuEls[1] = getSubElements()[0]; 585: } 586: else 587: { 588: menuEls = new MenuElement[1]; 589: menuEls[0] = this; 590: } 591: MenuSelectionManager.defaultManager().setSelectedPath(menuEls); 592: } 593: firePopupMenuWillBecomeVisible(); 594: PopupFactory pf = PopupFactory.getSharedInstance(); 595: pack(); 596: popup = pf.getPopup(invoker, this, popupLocationX, popupLocationY); 597: popup.show(); 598: } 599: else 600: { 601: getSelectionModel().clearSelection(); 602: firePopupMenuWillBecomeInvisible(); 603: popup.hide(); 604: } 605: firePropertyChange("visible", old, isVisible()); 606: } 607: } 608: 609: /** 610: * Sets location of the popup menu. 611: * 612: * @param x X coordinate of the popup menu's location 613: * @param y Y coordinate of the popup menu's location 614: */ 615: public void setLocation(int x, int y) 616: { 617: popupLocationX = x; 618: popupLocationY = y; 619: // Handle the case when the popup is already showing. In this case we need 620: // to fetch a new popup from PopupFactory and use this. See the general 621: // contract of the PopupFactory. 622: } 623: 624: /** 625: * Returns popup menu's invoker. 626: * 627: * @return popup menu's invoker 628: */ 629: public Component getInvoker() 630: { 631: return invoker; 632: } 633: 634: /** 635: * Sets popup menu's invoker. 636: * 637: * @param component The new invoker of this popup menu 638: */ 639: public void setInvoker(Component component) 640: { 641: invoker = component; 642: } 643: 644: /** 645: * This method displays JPopupMenu on the screen at the specified 646: * location. Note that x and y coordinates given to this method 647: * should be expressed in terms of the popup menus' invoker. 648: * 649: * @param component Invoker for this popup menu 650: * @param x x-coordinate of the popup menu relative to the specified invoker 651: * @param y y-coordiate of the popup menu relative to the specified invoker 652: */ 653: public void show(Component component, int x, int y) 654: { 655: if (component.isShowing()) 656: { 657: setInvoker(component); 658: Point p = new Point(x, y); 659: SwingUtilities.convertPointToScreen(p, component); 660: setLocation(p.x, p.y); 661: setVisible(true); 662: } 663: } 664: 665: /** 666: * Returns component located at the specified index in the popup menu 667: * 668: * @param index index of the component to return 669: * 670: * @return component located at the specified index in the popup menu 671: * 672: * @deprecated Replaced by getComponent(int) 673: */ 674: public Component getComponentAtIndex(int index) 675: { 676: return getComponent(index); 677: } 678: 679: /** 680: * Returns index of the specified component in the popup menu 681: * 682: * @param component Component to look for 683: * 684: * @return index of the specified component in the popup menu 685: */ 686: public int getComponentIndex(Component component) 687: { 688: Component[] items = getComponents(); 689: 690: for (int i = 0; i < items.length; i++) 691: { 692: if (items[i].equals(component)) 693: return i; 694: } 695: 696: return -1; 697: } 698: 699: /** 700: * Sets size of the popup 701: * 702: * @param size Dimensions representing new size of the popup menu 703: */ 704: public void setPopupSize(Dimension size) 705: { 706: super.setSize(size); 707: } 708: 709: /** 710: * Sets size of the popup menu 711: * 712: * @param width width for the new size 713: * @param height height for the new size 714: */ 715: public void setPopupSize(int width, int height) 716: { 717: super.setSize(width, height); 718: } 719: 720: /** 721: * Selects specified component in this popup menu. 722: * 723: * @param selected component to select 724: */ 725: public void setSelected(Component selected) 726: { 727: int index = getComponentIndex(selected); 728: selectionModel.setSelectedIndex(index); 729: } 730: 731: /** 732: * Checks if this popup menu paints its border. 733: * 734: * @return true if this popup menu paints its border and false otherwise. 735: */ 736: public boolean isBorderPainted() 737: { 738: return borderPainted; 739: } 740: 741: /** 742: * Sets if the border of the popup menu should be 743: * painter or not. 744: * 745: * @param painted true if the border should be painted and false otherwise 746: */ 747: public void setBorderPainted(boolean painted) 748: { 749: borderPainted = painted; 750: } 751: 752: /** 753: * Returns margin for this popup menu. 754: * 755: * @return margin for this popup menu. 756: */ 757: public Insets getMargin() 758: { 759: return margin; 760: } 761: 762: /** 763: * A string that describes this JPopupMenu. Normally only used 764: * for debugging. 765: * 766: * @return A string describing this JMenuItem 767: */ 768: protected String paramString() 769: { 770: StringBuffer sb = new StringBuffer(); 771: sb.append(super.paramString()); 772: sb.append(",label="); 773: if (getLabel() != null) 774: sb.append(getLabel()); 775: sb.append(",lightWeightPopupEnabled=").append(isLightWeightPopupEnabled()); 776: sb.append(",margin="); 777: if (getMargin() != null) 778: sb.append(margin); 779: sb.append(",paintBorder=").append(isBorderPainted()); 780: return sb.toString(); 781: } 782: 783: /** 784: * Process mouse events forwarded from MenuSelectionManager. This method 785: * doesn't do anything. It is here to conform to the MenuElement interface. 786: * 787: * @param event event forwarded from MenuSelectionManager 788: * @param path path to the menu element from which event was generated 789: * @param manager MenuSelectionManager for the current menu hierarchy 790: */ 791: public void processMouseEvent(MouseEvent event, MenuElement[] path, 792: MenuSelectionManager manager) 793: { 794: // Empty Implementation. This method is needed for the implementation 795: // of MenuElement interface 796: } 797: 798: /** 799: * Process key events forwarded from MenuSelectionManager. This method 800: * doesn't do anything. It is here to conform to the MenuElement interface. 801: * 802: * @param event event forwarded from MenuSelectionManager 803: * @param path path to the menu element from which event was generated 804: * @param manager MenuSelectionManager for the current menu hierarchy 805: * 806: */ 807: public void processKeyEvent(KeyEvent event, MenuElement[] path, 808: MenuSelectionManager manager) 809: { 810: // Empty Implementation. This method is needed for the implementation 811: // of MenuElement interface 812: } 813: 814: /** 815: * Method of MenuElement Interface. It is invoked when 816: * popupMenu's selection has changed 817: * 818: * @param changed true if this popupMenu is part of current menu 819: * hierarchy and false otherwise. 820: */ 821: public void menuSelectionChanged(boolean changed) 822: { 823: if (invoker instanceof JMenu) 824: { 825: // We need to special case this since the JMenu calculates the 826: // position etc of the popup. 827: JMenu menu = (JMenu) invoker; 828: menu.setPopupMenuVisible(changed); 829: } 830: else if (! changed) 831: setVisible(false); 832: } 833: 834: /** 835: * Return subcomonents of this popup menu. This method returns only 836: * components that implement the <code>MenuElement</code> interface. 837: * 838: * @return array of menu items belonging to this popup menu 839: */ 840: public MenuElement[] getSubElements() 841: { 842: Component[] items = getComponents(); 843: ArrayList subElements = new ArrayList(); 844: 845: for (int i = 0; i < items.length; i++) 846: if (items[i] instanceof MenuElement) 847: subElements.add(items[i]); 848: 849: return (MenuElement[]) 850: subElements.toArray(new MenuElement[subElements.size()]); 851: } 852: 853: /** 854: * Method of the MenuElement interface. Returns reference to itself. 855: * 856: * @return Returns reference to itself 857: */ 858: public Component getComponent() 859: { 860: return this; 861: } 862: 863: /** 864: * Checks if observing mouse event should trigger popup 865: * menu to show on the screen. 866: * 867: * @param event MouseEvent to check 868: * 869: * @return true if the observing mouse event is popup trigger and false otherwise 870: */ 871: public boolean isPopupTrigger(MouseEvent event) 872: { 873: return ((PopupMenuUI) getUI()).isPopupTrigger(event); 874: } 875: 876: /** 877: * DOCUMENT ME! 878: * 879: * @return DOCUMENT ME! 880: */ 881: public AccessibleContext getAccessibleContext() 882: { 883: if (accessibleContext == null) 884: accessibleContext = new AccessibleJPopupMenu(); 885: 886: return accessibleContext; 887: } 888: 889: /** 890: * This is the separator that can be used in popup menu. 891: */ 892: public static class Separator extends JSeparator 893: { 894: public Separator() 895: { 896: super(); 897: } 898: 899: public String getUIClassID() 900: { 901: return "PopupMenuSeparatorUI"; 902: } 903: } 904: 905: /** 906: * Returns <code>true</code> if the component is guaranteed to be painted 907: * on top of others. This returns false by default and is overridden by 908: * components like JMenuItem, JPopupMenu and JToolTip to return true for 909: * added efficiency. 910: * 911: * @return <code>true</code> if the component is guaranteed to be painted 912: * on top of others 913: */ 914: boolean onTop() 915: { 916: return true; 917: } 918: 919: protected class AccessibleJPopupMenu extends AccessibleJComponent 920: { 921: private static final long serialVersionUID = 7423261328879849768L; 922: 923: protected AccessibleJPopupMenu() 924: { 925: // Nothing to do here. 926: } 927: 928: public AccessibleRole getAccessibleRole() 929: { 930: return AccessibleRole.POPUP_MENU; 931: } 932: } 933: 934: /* This class resizes popup menu and repaints popup menu appropriately if one 935: of item's action has changed */ 936: private class ActionChangeListener implements PropertyChangeListener 937: { 938: public void propertyChange(PropertyChangeEvent evt) 939: { 940: // We used to have a revalidate() and repaint() call here. However I think 941: // this is not needed. Instead, a new Popup has to be fetched from the 942: // PopupFactory and used here. 943: } 944: } 945: }
GNU Classpath (0.95) |