Frames | No Frames |
1: /* Menu.java -- A Java AWT Menu 2: Copyright (C) 1999, 2002, 2004, 2006 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 java.awt; 40: 41: import java.awt.peer.MenuPeer; 42: import java.io.Serializable; 43: import java.util.Enumeration; 44: import java.util.Vector; 45: 46: import javax.accessibility.AccessibleContext; 47: import javax.accessibility.AccessibleRole; 48: 49: /** 50: * This class represents a pull down or tear off menu in Java's AWT. 51: * 52: * @author Aaron M. Renn (arenn@urbanophile.com) 53: */ 54: public class Menu extends MenuItem implements MenuContainer, Serializable 55: { 56: 57: /* 58: * Static Variables 59: */ 60: 61: /** 62: * The number used to generate the name returned by getName. 63: */ 64: private static transient long next_menu_number; 65: 66: // Serialization Constant 67: private static final long serialVersionUID = -8809584163345499784L; 68: 69: /*************************************************************************/ 70: 71: /* 72: * Instance Variables 73: */ 74: 75: /** 76: * @serial The actual items in the menu 77: */ 78: private Vector items = new Vector(); 79: 80: /** 81: * @serial Flag indicating whether or not this menu is a tear off 82: */ 83: private boolean tearOff; 84: 85: /** 86: * @serial Indicates whether or not this is a help menu. 87: */ 88: private boolean isHelpMenu; 89: 90: /* 91: * @serial Unused in this implementation, but present in Sun's 92: * serialization spec. Value obtained via reflection. 93: */ 94: private int menuSerializedDataVersion = 1; 95: 96: static final transient String separatorLabel = "-"; 97: 98: /*************************************************************************/ 99: 100: /* 101: * Constructors 102: */ 103: 104: /** 105: * Initializes a new instance of <code>Menu</code> with no label and that 106: * is not a tearoff; 107: * 108: * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. 109: */ 110: public 111: Menu() 112: { 113: } 114: 115: /*************************************************************************/ 116: 117: /** 118: * Initializes a new instance of <code>Menu</code> that is not a tearoff and 119: * that has the specified label. 120: * 121: * @param label The menu label. 122: * 123: * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. 124: */ 125: public 126: Menu(String label) 127: { 128: this(label, false); 129: } 130: 131: /*************************************************************************/ 132: 133: /** 134: * Initializes a new instance of <code>Menu</code> with the specified 135: * label and tearoff status. 136: * 137: * @param label The label for this menu 138: * @param isTearOff <code>true</code> if this menu is a tear off menu, 139: * <code>false</code> otherwise. 140: * 141: * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true. 142: */ 143: public 144: Menu(String label, boolean isTearOff) 145: { 146: super(label); 147: 148: tearOff = isTearOff; 149: 150: if (label.equals("Help")) 151: isHelpMenu = true; 152: 153: if (GraphicsEnvironment.isHeadless()) 154: throw new HeadlessException (); 155: } 156: 157: /*************************************************************************/ 158: 159: /* 160: * Instance Methods 161: */ 162: 163: /** 164: * Tests whether or not this menu is a tearoff. 165: * 166: * @return <code>true</code> if this menu is a tearoff, <code>false</code> 167: * otherwise. 168: */ 169: public boolean 170: isTearOff() 171: { 172: return(tearOff); 173: } 174: 175: /*************************************************************************/ 176: 177: /** 178: * Returns the number of items in this menu. 179: * 180: * @return The number of items in this menu. 181: */ 182: public int 183: getItemCount() 184: { 185: return countItems (); 186: } 187: 188: /** 189: * Returns the number of items in this menu. 190: * 191: * @return The number of items in this menu. 192: * 193: * @deprecated As of JDK 1.1, replaced by getItemCount(). 194: */ 195: public int countItems () 196: { 197: return items.size (); 198: } 199: 200: /*************************************************************************/ 201: 202: /** 203: * Returns the item at the specified index. 204: * 205: * @return The item at the specified index. 206: * 207: * @exception ArrayIndexOutOfBoundsException If the index value is not valid. 208: */ 209: public MenuItem 210: getItem(int index) 211: { 212: return((MenuItem)items.elementAt(index)); 213: } 214: 215: /*************************************************************************/ 216: 217: /** 218: * Adds the specified item to this menu. If it was previously part of 219: * another menu, it is first removed from that menu. 220: * 221: * @param item The new item to add. 222: * 223: * @return The item that was added. 224: */ 225: public MenuItem 226: add(MenuItem item) 227: { 228: MenuContainer parent = item.getParent(); 229: if (parent != null) 230: parent.remove(item); 231: 232: items.addElement(item); 233: item.setParent(this); 234: 235: if (peer != null) 236: { 237: item.addNotify(); 238: MenuPeer mp = (MenuPeer) peer; 239: mp.addItem(item); 240: } 241: 242: return item; 243: } 244: 245: /*************************************************************************/ 246: 247: /** 248: * Add an item with the specified label to this menu. 249: * 250: * @param label The label of the menu item to add. 251: */ 252: public void 253: add(String label) 254: { 255: add(new MenuItem(label)); 256: } 257: 258: /*************************************************************************/ 259: 260: /** 261: * Inserts the specified menu item into this menu at the specified index. 262: * 263: * @param item The menu item to add. 264: * @param index The index of the menu item. 265: * 266: * @exception IllegalArgumentException If the index is less than zero. 267: * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid. 268: */ 269: public void 270: insert(MenuItem item, int index) 271: { 272: if (index < 0) 273: throw new IllegalArgumentException("Index is less than zero"); 274: 275: int count = getItemCount (); 276: 277: if (index >= count) 278: add(item); 279: else 280: { 281: MenuContainer parent = item.getParent(); 282: if (parent != null) 283: parent.remove(item); 284: 285: items.insertElementAt(item, index); 286: item.setParent(this); 287: 288: MenuPeer peer = (MenuPeer) getPeer(); 289: if (peer == null) 290: return; 291: 292: for (int i = count - 1; i >= index; i--) 293: peer.delItem(i); 294: 295: item.addNotify(); 296: peer.addItem(item); 297: 298: for (int i = index; i < count; i++) 299: peer.addItem((MenuItem) items.elementAt (i)); 300: } 301: 302: } 303: 304: /*************************************************************************/ 305: 306: /** 307: * Inserts an item with the specified label into this menu at the specified index. 308: * 309: * @param label The label of the item to add. 310: * @param index The index of the menu item. 311: * 312: * @exception IllegalArgumentException If the index is less than zero. 313: * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid. 314: */ 315: public void 316: insert(String label, int index) 317: { 318: insert(new MenuItem(label), index); 319: } 320: 321: /*************************************************************************/ 322: 323: /** 324: * Adds a separator bar at the current menu location. 325: */ 326: public void 327: addSeparator() 328: { 329: add(new MenuItem(separatorLabel)); 330: } 331: 332: /*************************************************************************/ 333: 334: /** 335: * Inserts a separator bar at the specified index value. 336: * 337: * @param index The index at which to insert a separator bar. 338: * 339: * @exception IllegalArgumentException If the index is less than zero. 340: * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid. 341: */ 342: public void 343: insertSeparator(int index) 344: { 345: insert(new MenuItem(separatorLabel), index); 346: } 347: 348: /*************************************************************************/ 349: 350: /** 351: * Deletes the item at the specified index from this menu. 352: * 353: * @param index The index of the item to remove. 354: * 355: * @exception ArrayIndexOutOfBoundsException If the index is otherwise invalid. 356: */ 357: public synchronized void 358: remove(int index) 359: { 360: MenuItem item = (MenuItem) items.remove(index); 361: 362: MenuPeer mp = (MenuPeer) getPeer(); 363: if (mp != null) 364: { 365: mp.delItem(index); 366: item.removeNotify(); 367: } 368: item.setParent(null); 369: } 370: 371: /*************************************************************************/ 372: 373: /** 374: * Removes the specifed item from the menu. If the specified component 375: * does not exist, this method does nothing. 376: * 377: * @param item The component to remove. 378: */ 379: public void 380: remove(MenuComponent item) 381: { 382: int index = items.indexOf(item); 383: if (index == -1) 384: return; 385: 386: remove(index); 387: } 388: 389: /*************************************************************************/ 390: 391: /** 392: * Removes all the elements from this menu. 393: */ 394: public synchronized void 395: removeAll() 396: { 397: int count = getItemCount(); 398: for(int i = 0; i < count; i++) 399: { 400: // We must always remove item 0. 401: remove(0); 402: } 403: } 404: 405: /*************************************************************************/ 406: 407: /** 408: * Creates the native peer for this object. 409: */ 410: public void 411: addNotify() 412: { 413: MenuPeer peer = (MenuPeer) getPeer(); 414: if (peer == null) 415: { 416: peer = getToolkit().createMenu(this); 417: setPeer(peer); 418: } 419: 420: Enumeration e = items.elements(); 421: while (e.hasMoreElements()) 422: { 423: MenuItem mi = (MenuItem)e.nextElement(); 424: mi.addNotify(); 425: peer.addItem(mi); 426: } 427: 428: super.addNotify (); 429: } 430: 431: /*************************************************************************/ 432: 433: /** 434: * Destroys the native peer for this object. 435: */ 436: public void 437: removeNotify() 438: { 439: Enumeration e = items.elements(); 440: while (e.hasMoreElements()) 441: { 442: MenuItem mi = (MenuItem) e.nextElement(); 443: mi.removeNotify(); 444: } 445: super.removeNotify(); 446: } 447: 448: /*************************************************************************/ 449: 450: /** 451: * Returns a debugging string for this menu. 452: * 453: * @return A debugging string for this menu. 454: */ 455: public String 456: paramString() 457: { 458: return (",tearOff=" + tearOff + ",isHelpMenu=" + isHelpMenu 459: + super.paramString()); 460: } 461: 462: /** 463: * Basic Accessibility class for Menu. Details get provided in derived 464: * classes. 465: */ 466: protected class AccessibleAWTMenu extends AccessibleAWTMenuItem 467: { 468: private static final long serialVersionUID = 5228160894980069094L; 469: 470: protected AccessibleAWTMenu() 471: { 472: } 473: 474: public AccessibleRole getAccessibleRole() 475: { 476: return AccessibleRole.MENU; 477: } 478: } 479: 480: /** 481: * Gets the AccessibleContext associated with this <code>Menu</code>. 482: * The context is created, if necessary. 483: * 484: * @return the associated context 485: */ 486: public AccessibleContext getAccessibleContext() 487: { 488: /* Create the context if this is the first request */ 489: if (accessibleContext == null) 490: accessibleContext = new AccessibleAWTMenu(); 491: return accessibleContext; 492: } 493: 494: /** 495: * Generate a unique name for this <code>Menu</code>. 496: * 497: * @return A unique name for this <code>Menu</code>. 498: */ 499: String generateName() 500: { 501: return "menu" + getUniqueLong(); 502: } 503: 504: private static synchronized long getUniqueLong() 505: { 506: return next_menu_number++; 507: } 508: 509: } // class Menu