| 1 7 8 package javax.swing; 9 10 import java.awt.AWTEvent ; 11 import java.awt.Component ; 12 import java.awt.ComponentOrientation ; 13 import java.awt.Container ; 14 import java.awt.Dimension ; 15 import java.awt.Frame ; 16 import java.awt.Graphics ; 17 import java.awt.GraphicsConfiguration ; 18 import java.awt.GraphicsDevice ; 19 import java.awt.GraphicsEnvironment ; 20 import java.awt.Insets ; 21 import java.awt.Point ; 22 import java.awt.Polygon ; 23 import java.awt.Rectangle ; 24 import java.awt.Toolkit ; 25 import java.awt.event.*; 26 import java.beans.*; 27 28 import java.util.*; 29 30 import java.io.Serializable ; 31 import java.io.ObjectOutputStream ; 32 import java.io.ObjectInputStream ; 33 import java.io.IOException ; 34 35 import javax.swing.event.*; 36 import javax.swing.plaf.*; 37 import javax.swing.plaf.basic.*; 38 import javax.accessibility.*; 39 40 import java.lang.ref.WeakReference ; 41 42 81 public class JMenu extends JMenuItem implements Accessible,MenuElement  82 { 83 87 private static final String uiClassID = "MenuUI"; 88 89 92 private JPopupMenu popupMenu; 93 94 97 private ChangeListener menuChangeListener = null; 98 99 104 private MenuEvent menuEvent = null; 105 106 111 private static Hashtable listenerRegistry = null; 112 113 117 private int delay; 118 119 123 private Point customMenuLocation = null; 124 125 126 private static final boolean TRACE = false; private static final boolean VERBOSE = false; private static final boolean DEBUG = false; 130 133 public JMenu() { 134 this(""); 135 } 136 137 143 public JMenu(String s) { 144 super(s); 145 } 146 147 154 public JMenu(Action a) { 155 this(); 156 setAction(a); 157 } 158 159 166 public JMenu(String s, boolean b) { 167 this(s); 168 } 169 170 171 183 void initFocusability() { 184 } 185 186 191 public void updateUI() { 192 setUI((MenuItemUI)UIManager.getUI(this)); 193 194 if ( popupMenu != null ) 195 { 196 popupMenu.setUI((PopupMenuUI)UIManager.getUI(popupMenu)); 197 } 198 199 } 200 201 202 209 public String getUIClassID() { 210 return uiClassID; 211 } 212 213 218 230 public void setModel(ButtonModel newModel) { 231 ButtonModel oldModel = getModel(); 232 233 super.setModel(newModel); 234 235 if (oldModel != null && menuChangeListener != null) { 236 oldModel.removeChangeListener(menuChangeListener); 237 menuChangeListener = null; 238 } 239 240 model = newModel; 241 242 if (newModel != null) { 243 menuChangeListener = createMenuChangeListener(); 244 newModel.addChangeListener(menuChangeListener); 245 } 246 } 247 248 253 public boolean isSelected() { 254 return getModel().isSelected(); 255 } 256 257 267 public void setSelected(boolean b) { 268 ButtonModel model = getModel(); 269 boolean oldValue = model.isSelected(); 270 271 279 if (b != model.isSelected()) { 280 getModel().setSelected(b); 281 } 282 } 283 284 289 public boolean isPopupMenuVisible() { 290 ensurePopupMenuCreated(); 291 return popupMenu.isVisible(); 292 } 293 294 305 public void setPopupMenuVisible(boolean b) { 306 if (DEBUG) { 307 System.out.println("in JMenu.setPopupMenuVisible " + b); 308 } 310 311 boolean isVisible = isPopupMenuVisible(); 312 if (b != isVisible && (isEnabled() || !b)) { 313 ensurePopupMenuCreated(); 314 if ((b==true) && isShowing()) { 315 Point p = getCustomMenuLocation(); 317 if (p == null) { 318 p = getPopupMenuOrigin(); 319 } 320 getPopupMenu().show(this, p.x, p.y); 321 } else { 322 getPopupMenu().setVisible(false); 323 } 324 } 325 326 } 327 328 343 protected Point getPopupMenuOrigin() { 344 int x = 0; 345 int y = 0; 346 JPopupMenu pm = getPopupMenu(); 347 Dimension s = getSize(); 349 Dimension pmSize = pm.getSize(); 350 if (pmSize.width==0) { 353 pmSize = pm.getPreferredSize(); 354 } 355 Point position = getLocationOnScreen(); 356 Toolkit toolkit = Toolkit.getDefaultToolkit(); 357 GraphicsConfiguration gc = getGraphicsConfiguration(); 358 Rectangle screenBounds = new Rectangle (toolkit.getScreenSize()); 359 GraphicsEnvironment ge = 360 GraphicsEnvironment.getLocalGraphicsEnvironment(); 361 GraphicsDevice [] gd = ge.getScreenDevices(); 362 for(int i = 0; i < gd.length; i++) { 363 if(gd[i].getType() == GraphicsDevice.TYPE_RASTER_SCREEN) { 364 GraphicsConfiguration dgc = 365 gd[i].getDefaultConfiguration(); 366 if(dgc.getBounds().contains(position)) { 367 gc = dgc; 368 break; 369 } 370 } 371 } 372 373 374 if (gc != null) { 375 screenBounds = gc.getBounds(); 376 Insets screenInsets = toolkit.getScreenInsets(gc); 378 379 screenBounds.width -= 380 Math.abs(screenInsets.left + screenInsets.right); 381 screenBounds.height -= 382 Math.abs(screenInsets.top + screenInsets.bottom); 383 position.x -= Math.abs(screenInsets.left); 384 position.y -= Math.abs(screenInsets.top); 385 } 386 387 Container parent = getParent(); 388 if (parent instanceof JPopupMenu ) { 389 int xOffset = UIManager.getInt("Menu.submenuPopupOffsetX"); 391 int yOffset = UIManager.getInt("Menu.submenuPopupOffsetY"); 392 393 if( SwingUtilities.isLeftToRight(this) ) { 394 x = s.width + xOffset; if (position.x + x + pmSize.width >= screenBounds.width 397 + screenBounds.x && 398 screenBounds.width - s.width < 2*(position.x 400 - screenBounds.x)) { 401 402 x = 0 - xOffset - pmSize.width; 403 } 404 } else { 405 x = 0 - xOffset - pmSize.width; if (position.x + x < screenBounds.x && 408 screenBounds.width - s.width > 2*(position.x - 410 screenBounds.x)) { 411 412 x = s.width + xOffset; 413 } 414 } 415 y = yOffset; if (position.y + y + pmSize.height >= screenBounds.height 418 + screenBounds.y && 419 screenBounds.height - s.height < 2*(position.y 421 - screenBounds.y)) { 422 423 y = s.height - yOffset - pmSize.height; 424 } 425 } else { 426 int xOffset = UIManager.getInt("Menu.menuPopupOffsetX"); 428 int yOffset = UIManager.getInt("Menu.menuPopupOffsetY"); 429 430 if( SwingUtilities.isLeftToRight(this) ) { 431 x = xOffset; if (position.x + x + pmSize.width >= screenBounds.width 434 + screenBounds.x && 435 screenBounds.width - s.width < 2*(position.x 437 - screenBounds.x)) { 438 439 x = s.width - xOffset - pmSize.width; 440 } 441 } else { 442 x = s.width - xOffset - pmSize.width; if (position.x + x < screenBounds.x && 445 screenBounds.width - s.width > 2*(position.x 447 - screenBounds.x)) { 448 449 x = xOffset; 450 } 451 } 452 y = s.height + yOffset; if (position.y + y + pmSize.height >= screenBounds.height && 455 screenBounds.height - s.height < 2*(position.y 457 - screenBounds.y)) { 458 459 y = 0 - yOffset - pmSize.height; } 461 } 462 return new Point (x,y); 463 } 464 465 466 479 public int getDelay() { 480 return delay; 481 } 482 483 498 public void setDelay(int d) { 499 if (d < 0) 500 throw new IllegalArgumentException ("Delay must be a positive integer"); 501 502 delay = d; 503 } 504 505 510 protected WinListener popupListener; 511 512 private void ensurePopupMenuCreated() { 513 if (popupMenu == null) { 514 final JMenu thisMenu = this; 515 this.popupMenu = new JPopupMenu (); 516 popupMenu.setInvoker(this); 517 popupListener = createWinListener(popupMenu); 518 } 519 } 520 521 524 private Point getCustomMenuLocation() { 525 return customMenuLocation; 526 } 527 528 534 public void setMenuLocation(int x, int y) { 535 customMenuLocation = new Point (x, y); 536 if (popupMenu != null) 537 popupMenu.setLocation(x, y); 538 } 539 540 547 public JMenuItem add(JMenuItem menuItem) { 548 AccessibleContext ac = menuItem.getAccessibleContext(); 549 ac.setAccessibleParent(this); 550 ensurePopupMenuCreated(); 551 return popupMenu.add(menuItem); 552 } 553 554 561 public Component add(Component c) { 562 if (c instanceof JComponent ) { 563 AccessibleContext ac = ((JComponent ) c).getAccessibleContext(); 564 if (ac != null) { 565 ac.setAccessibleParent(this); 566 } 567 } 568 ensurePopupMenuCreated(); 569 popupMenu.add(c); 570 return c; 571 } 572 573 583 public Component add(Component c, int index) { 584 if (c instanceof JComponent ) { 585 AccessibleContext ac = ((JComponent ) c).getAccessibleContext(); 586 if (ac != null) { 587 ac.setAccessibleParent(this); 588 } 589 } 590 ensurePopupMenuCreated(); 591 popupMenu.add(c, index); 592 return c; 593 } 594 595 601 public JMenuItem add(String s) { 602 return add(new JMenuItem (s)); 603 } 604 605 618 public JMenuItem add(Action a) { 619 JMenuItem mi = createActionComponent(a); 620 mi.setAction(a); 621 add(mi); 622 return mi; 623 } 624 625 640 protected JMenuItem createActionComponent(Action a) { 641 JMenuItem mi = new JMenuItem ((String )a.getValue(Action.NAME), 642 (Icon )a.getValue(Action.SMALL_ICON)){ 643 protected PropertyChangeListener createActionPropertyChangeListener(Action a) { 644 PropertyChangeListener pcl = createActionChangeListener(this); 645 if (pcl == null) { 646 pcl = super.createActionPropertyChangeListener(a); 647 } 648 return pcl; 649 } 650 }; 651 mi.setHorizontalTextPosition(JButton.TRAILING); 652 mi.setVerticalTextPosition(JButton.CENTER); 653 mi.setEnabled(a.isEnabled()); 654 return mi; 655 } 656 657 667 protected PropertyChangeListener createActionChangeListener(JMenuItem b) { 668 return new ActionChangedListener(b); 669 } 670 671 private class ActionChangedListener implements PropertyChangeListener { 672 WeakReference menuItem; 673 674 ActionChangedListener(JMenuItem mi) { 675 super(); 676 setTarget(mi); 677 } 678 public void propertyChange(PropertyChangeEvent e) { 679 String propertyName = e.getPropertyName(); 680 JMenuItem mi = (JMenuItem )getTarget(); 681 if (mi == null) { 682 Action action = (Action )e.getSource(); 683 action.removePropertyChangeListener(this); 684 } else { 685 if (propertyName.equals(Action.NAME)) { 686 String text = (String ) e.getNewValue(); 687 mi.setText(text); 688 } else if (propertyName.equals("enabled")) { 689 Boolean enabledState = (Boolean ) e.getNewValue(); 690 mi.setEnabled(enabledState.booleanValue()); 691 } else if (propertyName.equals(Action.SMALL_ICON)) { 692 Icon icon = (Icon ) e.getNewValue(); 693 mi.setIcon(icon); 694 mi.invalidate(); 695 mi.repaint(); 696 } else if (propertyName.equals(Action.ACTION_COMMAND_KEY)) { 697 mi.setActionCommand((String )e.getNewValue()); 698 } 699 } 700 } 701 public void setTarget(JMenuItem b) { 702 menuItem = new WeakReference (b); 703 } 704 public JMenuItem getTarget() { 705 return (JMenuItem )menuItem.get(); 706 } 707 } 708 709 712 public void addSeparator() 713 { 714 ensurePopupMenuCreated(); 715 popupMenu.addSeparator(); 716 } 717 718 728 public void insert(String s, int pos) { 729 if (pos < 0) { 730 throw new IllegalArgumentException ("index less than zero."); 731 } 732 733 ensurePopupMenuCreated(); 734 popupMenu.insert(new JMenuItem (s), pos); 735 } 736 737 747 public JMenuItem insert(JMenuItem mi, int pos) { 748 if (pos < 0) { 749 throw new IllegalArgumentException ("index less than zero."); 750 } 751 AccessibleContext ac = mi.getAccessibleContext(); 752 ac.setAccessibleParent(this); 753 ensurePopupMenuCreated(); 754 popupMenu.insert(mi, pos); 755 return mi; 756 } 757 758 768 public JMenuItem insert(Action a, int pos) { 769 if (pos < 0) { 770 throw new IllegalArgumentException ("index less than zero."); 771 } 772 773 ensurePopupMenuCreated(); 774 JMenuItem mi = new JMenuItem ((String )a.getValue(Action.NAME), 775 (Icon )a.getValue(Action.SMALL_ICON)); 776 mi.setHorizontalTextPosition(JButton.TRAILING); 777 mi.setVerticalTextPosition(JButton.CENTER); 778 mi.setEnabled(a.isEnabled()); 779 mi.setAction(a); 780 popupMenu.insert(mi, pos); 781 return mi; 782 } 783 784 792 public void insertSeparator(int index) { 793 if (index < 0) { 794 throw new IllegalArgumentException ("index less than zero."); 795 } 796 797 ensurePopupMenuCreated(); 798 popupMenu.insert( new JPopupMenu.Separator (), index ); 799 } 800 801 813 public JMenuItem getItem(int pos) { 814 if (pos < 0) { 815 throw new IllegalArgumentException ("index less than zero."); 816 } 817 818 Component c = getMenuComponent(pos); 819 if (c instanceof JMenuItem ) { 820 JMenuItem mi = (JMenuItem ) c; 821 return mi; 822 } 823 824 return null; 826 } 827 828 835 public int getItemCount() { 836 return getMenuComponentCount(); 837 } 838 839 846 public boolean isTearOff() { 847 throw new Error ("boolean isTearOff() {} not yet implemented"); 848 } 849 850 856 public void remove(JMenuItem item) { 857 if (popupMenu != null) 858 popupMenu.remove(item); 859 } 860 861 869 public void remove(int pos) { 870 if (pos < 0) { 871 throw new IllegalArgumentException ("index less than zero."); 872 } 873 if (pos > getItemCount()) { 874 throw new IllegalArgumentException ("index greater than the number of items."); 875 } 876 if (popupMenu != null) 877 popupMenu.remove(pos); 878 } 879 880 885 public void remove(Component c) { 886 if (popupMenu != null) 887 popupMenu.remove(c); 888 } 889 890 |