rev 47711 : Fixed JDK-8178430: JMenu in GridBagLayout flickers when label text shows "..."
and is updated.
JDK-8178430: Fixed following issues with the test:
1. Throw exception in case the menu bar size is not proper.
2. Run the test for about 10 seconds, and then automatically
close the window.
3. Moved the fix from BasicMenuItemUI.java to BasicMenuUI.java
as per Sergey's suggestion.
4. Fixed the test case to correct the access to UI elements in EDT. Also, now made
sure that the main thread won't exit until the test is complete.
5.Removed unnecessary space in BasicMenuItemUI.java
6. Removed unnecessary import.
7. Moved the declaration of member variables into the constructor scope.
8. Fixed the test case to update/access all the swing components inside
SwingUtilities->invokeLater.
9. Modified the fix as suggested by Sergey.

   1 /*
   2  * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing.plaf.basic;
  27 
  28 import sun.swing.DefaultLookup;
  29 import sun.swing.UIAction;
  30 import java.awt.*;
  31 import java.awt.event.*;
  32 import java.beans.*;
  33 import javax.swing.*;
  34 import javax.swing.event.*;
  35 import javax.swing.plaf.*;
  36 import javax.swing.border.*;
  37 import java.util.Arrays;
  38 import java.util.ArrayList;
  39 
  40 
  41 /**
  42  * A default L&F implementation of MenuUI.  This implementation
  43  * is a "combined" view/controller.
  44  *
  45  * @author Georges Saab
  46  * @author David Karlton
  47  * @author Arnaud Weber
  48  */
  49 public class BasicMenuUI extends BasicMenuItemUI
  50 {
  51     /**
  52      * The instance of {@code ChangeListener}.
  53      */
  54     protected ChangeListener         changeListener;
  55 
  56     /**
  57      * The instance of {@code MenuListener}.
  58      */
  59     protected MenuListener           menuListener;
  60 
  61     private int lastMnemonic = 0;
  62 
  63     /** Uses as the parent of the windowInputMap when selected. */
  64     private InputMap selectedWindowInputMap;
  65 
  66     /* diagnostic aids -- should be false for production builds. */
  67     private static final boolean TRACE =   false; // trace creates and disposes
  68     private static final boolean VERBOSE = false; // show reuse hits/misses
  69     private static final boolean DEBUG =   false;  // show bad params, misc.
  70 
  71     private static boolean crossMenuMnemonic = true;
  72 
  73     /**
  74      * Constructs a new instance of {@code BasicMenuUI}.
  75      *
  76      * @param x a component
  77      * @return a new instance of {@code BasicMenuUI}
  78      */
  79     public static ComponentUI createUI(JComponent x) {
  80         return new BasicMenuUI();
  81     }
  82 
  83     static void loadActionMap(LazyActionMap map) {
  84         BasicMenuItemUI.loadActionMap(map);
  85         map.put(new Actions(Actions.SELECT, null, true));
  86     }
  87 
  88 
  89     protected void installDefaults() {
  90         super.installDefaults();
  91         updateDefaultBackgroundColor();
  92         ((JMenu)menuItem).setDelay(200);
  93         crossMenuMnemonic = UIManager.getBoolean("Menu.crossMenuMnemonic");
  94     }
  95 
  96     protected String getPropertyPrefix() {
  97         return "Menu";
  98     }
  99 
 100     protected void installListeners() {
 101         super.installListeners();
 102 
 103         if (changeListener == null)
 104             changeListener = createChangeListener(menuItem);
 105 
 106         if (changeListener != null)
 107             menuItem.addChangeListener(changeListener);
 108 
 109         if (menuListener == null)
 110             menuListener = createMenuListener(menuItem);
 111 
 112         if (menuListener != null)
 113             ((JMenu)menuItem).addMenuListener(menuListener);
 114     }
 115 
 116     protected void installKeyboardActions() {
 117         super.installKeyboardActions();
 118         updateMnemonicBinding();
 119     }
 120 
 121     void installLazyActionMap() {
 122         LazyActionMap.installLazyActionMap(menuItem, BasicMenuUI.class,
 123                                            getPropertyPrefix() + ".actionMap");
 124     }
 125 
 126     @SuppressWarnings("deprecation")
 127     void updateMnemonicBinding() {
 128         int mnemonic = menuItem.getModel().getMnemonic();
 129         int[] shortcutKeys = (int[])DefaultLookup.get(menuItem, this,
 130                                                    "Menu.shortcutKeys");
 131         if (shortcutKeys == null) {
 132             shortcutKeys = new int[] {KeyEvent.ALT_MASK};
 133         }
 134         if (mnemonic == lastMnemonic) {
 135             return;
 136         }
 137         InputMap windowInputMap = SwingUtilities.getUIInputMap(
 138                        menuItem, JComponent.WHEN_IN_FOCUSED_WINDOW);
 139         if (lastMnemonic != 0 && windowInputMap != null) {
 140             for (int shortcutKey : shortcutKeys) {
 141                 windowInputMap.remove(KeyStroke.getKeyStroke
 142                         (lastMnemonic, shortcutKey, false));
 143             }
 144         }
 145         if (mnemonic != 0) {
 146             if (windowInputMap == null) {
 147                 windowInputMap = createInputMap(JComponent.
 148                                               WHEN_IN_FOCUSED_WINDOW);
 149                 SwingUtilities.replaceUIInputMap(menuItem, JComponent.
 150                                        WHEN_IN_FOCUSED_WINDOW, windowInputMap);
 151             }
 152             for (int shortcutKey : shortcutKeys) {
 153                 windowInputMap.put(KeyStroke.getKeyStroke(mnemonic,
 154                         shortcutKey, false), "selectMenu");
 155             }
 156         }
 157         lastMnemonic = mnemonic;
 158     }
 159 
 160     protected void uninstallKeyboardActions() {
 161         super.uninstallKeyboardActions();
 162         lastMnemonic = 0;
 163     }
 164 
 165     protected MouseInputListener createMouseInputListener(JComponent c) {
 166         return getHandler();
 167     }
 168 
 169     /**
 170      * Returns an instance of {@code MenuListener}.
 171      *
 172      * @param c a component
 173      * @return an instance of {@code MenuListener}
 174      */
 175     protected MenuListener createMenuListener(JComponent c) {
 176         return null;
 177     }
 178 
 179     /**
 180      * Returns an instance of {@code ChangeListener}.
 181      *
 182      * @param c a component
 183      * @return an instance of {@code ChangeListener}
 184      */
 185     protected ChangeListener createChangeListener(JComponent c) {
 186         return null;
 187     }
 188 
 189     protected PropertyChangeListener createPropertyChangeListener(JComponent c) {
 190         return getHandler();
 191     }
 192 
 193     BasicMenuItemUI.Handler getHandler() {
 194         if (handler == null) {
 195             handler = new Handler();
 196         }
 197         return handler;
 198     }
 199 
 200     protected void uninstallDefaults() {
 201         menuItem.setArmed(false);
 202         menuItem.setSelected(false);
 203         menuItem.resetKeyboardActions();
 204         super.uninstallDefaults();
 205     }
 206 
 207     protected void uninstallListeners() {
 208         super.uninstallListeners();
 209 
 210         if (changeListener != null)
 211             menuItem.removeChangeListener(changeListener);
 212 
 213         if (menuListener != null)
 214             ((JMenu)menuItem).removeMenuListener(menuListener);
 215 
 216         changeListener = null;
 217         menuListener = null;
 218         handler = null;
 219     }
 220 
 221     protected MenuDragMouseListener createMenuDragMouseListener(JComponent c) {
 222         return getHandler();
 223     }
 224 
 225     protected MenuKeyListener createMenuKeyListener(JComponent c) {
 226         return (MenuKeyListener)getHandler();
 227     }
 228 





 229     public Dimension getMaximumSize(JComponent c) {
 230         if (((JMenu)menuItem).isTopLevelMenu() == true) {
 231             Dimension d = c.getPreferredSize();
 232             return new Dimension(d.width, Short.MAX_VALUE);
 233         }
 234         return null;
 235     }
 236 
 237     /**
 238      * Sets timer to the {@code menu}.
 239      *
 240      * @param menu an instance of {@code JMenu}.
 241      */
 242     protected void setupPostTimer(JMenu menu) {
 243         Timer timer = new Timer(menu.getDelay(), new Actions(
 244                                     Actions.SELECT, menu,false));
 245         timer.setRepeats(false);
 246         timer.start();
 247     }
 248 
 249     private static void appendPath(MenuElement[] path, MenuElement elem) {
 250         MenuElement newPath[] = new MenuElement[path.length+1];
 251         System.arraycopy(path, 0, newPath, 0, path.length);
 252         newPath[path.length] = elem;
 253         MenuSelectionManager.defaultManager().setSelectedPath(newPath);
 254     }
 255 
 256     private static class Actions extends UIAction {
 257         private static final String SELECT = "selectMenu";
 258 
 259         // NOTE: This will be null if the action is registered in the
 260         // ActionMap. For the timer use it will be non-null.
 261         private JMenu menu;
 262         private boolean force=false;
 263 
 264         Actions(String key, JMenu menu, boolean shouldForce) {
 265             super(key);
 266             this.menu = menu;
 267             this.force = shouldForce;
 268         }
 269 
 270         private JMenu getMenu(ActionEvent e) {
 271             if (e.getSource() instanceof JMenu) {
 272                 return (JMenu)e.getSource();
 273             }
 274             return menu;
 275         }
 276 
 277         public void actionPerformed(ActionEvent e) {
 278             JMenu menu = getMenu(e);
 279             if (!crossMenuMnemonic) {
 280                 JPopupMenu pm = BasicPopupMenuUI.getLastPopup();
 281                 if (pm != null && pm != menu.getParent()) {
 282                     return;
 283                 }
 284             }
 285 
 286             final MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
 287             if(force) {
 288                 Container cnt = menu.getParent();
 289                 if(cnt != null && cnt instanceof JMenuBar) {
 290                     MenuElement me[];
 291                     MenuElement subElements[];
 292 
 293                     subElements = menu.getPopupMenu().getSubElements();
 294                     if(subElements.length > 0) {
 295                         me = new MenuElement[4];
 296                         me[0] = (MenuElement) cnt;
 297                         me[1] = menu;
 298                         me[2] = menu.getPopupMenu();
 299                         me[3] = subElements[0];
 300                     } else {
 301                         me = new MenuElement[3];
 302                         me[0] = (MenuElement)cnt;
 303                         me[1] = menu;
 304                         me[2] = menu.getPopupMenu();
 305                     }
 306                     defaultManager.setSelectedPath(me);
 307                 }
 308             } else {
 309                 MenuElement path[] = defaultManager.getSelectedPath();
 310                 if(path.length > 0 && path[path.length-1] == menu) {
 311                     appendPath(path, menu.getPopupMenu());
 312                 }
 313             }
 314         }
 315 
 316         @Override
 317         public boolean accept(Object c) {
 318             if (c instanceof JMenu) {
 319                 return ((JMenu)c).isEnabled();
 320             }
 321             return true;
 322         }
 323     }
 324 
 325     /*
 326      * Set the background color depending on whether this is a toplevel menu
 327      * in a menubar or a submenu of another menu.
 328      */
 329     private void updateDefaultBackgroundColor() {
 330         if (!UIManager.getBoolean("Menu.useMenuBarBackgroundForTopLevel")) {
 331            return;
 332         }
 333         JMenu menu = (JMenu)menuItem;
 334         if (menu.getBackground() instanceof UIResource) {
 335             if (menu.isTopLevelMenu()) {
 336                 menu.setBackground(UIManager.getColor("MenuBar.background"));
 337             } else {
 338                 menu.setBackground(UIManager.getColor(getPropertyPrefix() + ".background"));
 339             }
 340         }
 341     }
 342 
 343     /**
 344      * Instantiated and used by a menu item to handle the current menu selection
 345      * from mouse events. A MouseInputHandler processes and forwards all mouse events
 346      * to a shared instance of the MenuSelectionManager.
 347      * <p>
 348      * This class is protected so that it can be subclassed by other look and
 349      * feels to implement their own mouse handling behavior. All overridden
 350      * methods should call the parent methods so that the menu selection
 351      * is correct.
 352      *
 353      * @see javax.swing.MenuSelectionManager
 354      * @since 1.4
 355      */
 356     protected class MouseInputHandler implements MouseInputListener {
 357         // NOTE: This class exists only for backward compatibility. All
 358         // its functionality has been moved into Handler. If you need to add
 359         // new functionality add it to the Handler, but make sure this
 360         // class calls into the Handler.
 361 
 362         public void mouseClicked(MouseEvent e) {
 363             getHandler().mouseClicked(e);
 364         }
 365 
 366         /**
 367          * Invoked when the mouse has been clicked on the menu. This
 368          * method clears or sets the selection path of the
 369          * MenuSelectionManager.
 370          *
 371          * @param e the mouse event
 372          */
 373         public void mousePressed(MouseEvent e) {
 374             getHandler().mousePressed(e);
 375         }
 376 
 377         /**
 378          * Invoked when the mouse has been released on the menu. Delegates the
 379          * mouse event to the MenuSelectionManager.
 380          *
 381          * @param e the mouse event
 382          */
 383         public void mouseReleased(MouseEvent e) {
 384             getHandler().mouseReleased(e);
 385         }
 386 
 387         /**
 388          * Invoked when the cursor enters the menu. This method sets the selected
 389          * path for the MenuSelectionManager and handles the case
 390          * in which a menu item is used to pop up an additional menu, as in a
 391          * hierarchical menu system.
 392          *
 393          * @param e the mouse event; not used
 394          */
 395         public void mouseEntered(MouseEvent e) {
 396             getHandler().mouseEntered(e);
 397         }
 398         public void mouseExited(MouseEvent e) {
 399             getHandler().mouseExited(e);
 400         }
 401 
 402         /**
 403          * Invoked when a mouse button is pressed on the menu and then dragged.
 404          * Delegates the mouse event to the MenuSelectionManager.
 405          *
 406          * @param e the mouse event
 407          * @see java.awt.event.MouseMotionListener#mouseDragged
 408          */
 409         public void mouseDragged(MouseEvent e) {
 410             getHandler().mouseDragged(e);
 411         }
 412 
 413         public void mouseMoved(MouseEvent e) {
 414             getHandler().mouseMoved(e);
 415         }
 416     }
 417 
 418     /**
 419      * As of Java 2 platform 1.4, this previously undocumented class
 420      * is now obsolete. KeyBindings are now managed by the popup menu.
 421      */
 422     public class ChangeHandler implements ChangeListener {
 423         /**
 424          * The instance of {@code JMenu}.
 425          */
 426         public JMenu    menu;
 427 
 428         /**
 429          * The instance of {@code BasicMenuUI}.
 430          */
 431         public BasicMenuUI ui;
 432 
 433         /**
 434          * {@code true} if an item of popup menu is selected.
 435          */
 436         public boolean  isSelected = false;
 437 
 438         /**
 439          * The component that was focused.
 440          */
 441         public Component wasFocused;
 442 
 443         /**
 444          * Constructs a new instance of {@code ChangeHandler}.
 445          *
 446          * @param m an instance of {@code JMenu}
 447          * @param ui an instance of {@code BasicMenuUI}
 448          */
 449         public ChangeHandler(JMenu m, BasicMenuUI ui) {
 450             menu = m;
 451             this.ui = ui;
 452         }
 453 
 454         public void stateChanged(ChangeEvent e) { }
 455     }
 456 
 457     private class Handler extends BasicMenuItemUI.Handler implements MenuKeyListener {
 458         //
 459         // PropertyChangeListener
 460         //
 461         public void propertyChange(PropertyChangeEvent e) {
 462             if (e.getPropertyName() == AbstractButton.
 463                              MNEMONIC_CHANGED_PROPERTY) {
 464                 updateMnemonicBinding();
 465             }
 466             else {
 467                 if (e.getPropertyName().equals("ancestor")) {
 468                     updateDefaultBackgroundColor();
 469                 }
 470                 super.propertyChange(e);
 471             }
 472         }
 473 
 474         //
 475         // MouseInputListener
 476         //
 477         public void mouseClicked(MouseEvent e) {
 478         }
 479 
 480         /**
 481          * Invoked when the mouse has been clicked on the menu. This
 482          * method clears or sets the selection path of the
 483          * MenuSelectionManager.
 484          *
 485          * @param e the mouse event
 486          */
 487         public void mousePressed(MouseEvent e) {
 488             JMenu menu = (JMenu)menuItem;
 489             if (!menu.isEnabled())
 490                 return;
 491 
 492             MenuSelectionManager manager =
 493                 MenuSelectionManager.defaultManager();
 494             if(menu.isTopLevelMenu()) {
 495                 if(menu.isSelected() && menu.getPopupMenu().isShowing()) {
 496                     manager.clearSelectedPath();
 497                 } else {
 498                     Container cnt = menu.getParent();
 499                     if(cnt != null && cnt instanceof JMenuBar) {
 500                         MenuElement me[] = new MenuElement[2];
 501                         me[0]=(MenuElement)cnt;
 502                         me[1]=menu;
 503                         manager.setSelectedPath(me);
 504                     }
 505                 }
 506             }
 507 
 508             MenuElement selectedPath[] = manager.getSelectedPath();
 509             if (selectedPath.length > 0 &&
 510                 selectedPath[selectedPath.length-1] != menu.getPopupMenu()) {
 511 
 512                 if(menu.isTopLevelMenu() ||
 513                    menu.getDelay() == 0) {
 514                     appendPath(selectedPath, menu.getPopupMenu());
 515                 } else {
 516                     setupPostTimer(menu);
 517                 }
 518             }
 519         }
 520 
 521         /**
 522          * Invoked when the mouse has been released on the menu. Delegates the
 523          * mouse event to the MenuSelectionManager.
 524          *
 525          * @param e the mouse event
 526          */
 527         public void mouseReleased(MouseEvent e) {
 528             JMenu menu = (JMenu)menuItem;
 529             if (!menu.isEnabled())
 530                 return;
 531             MenuSelectionManager manager =
 532                 MenuSelectionManager.defaultManager();
 533             manager.processMouseEvent(e);
 534             if (!e.isConsumed())
 535                 manager.clearSelectedPath();
 536         }
 537 
 538         /**
 539          * Invoked when the cursor enters the menu. This method sets the selected
 540          * path for the MenuSelectionManager and handles the case
 541          * in which a menu item is used to pop up an additional menu, as in a
 542          * hierarchical menu system.
 543          *
 544          * @param e the mouse event; not used
 545          */
 546         public void mouseEntered(MouseEvent e) {
 547             JMenu menu = (JMenu)menuItem;
 548             // only disable the menu highlighting if it's disabled and the property isn't
 549             // true. This allows disabled rollovers to work in WinL&F
 550             if (!menu.isEnabled() && !UIManager.getBoolean("MenuItem.disabledAreNavigable")) {
 551                 return;
 552             }
 553 
 554             MenuSelectionManager manager =
 555                 MenuSelectionManager.defaultManager();
 556             MenuElement selectedPath[] = manager.getSelectedPath();
 557             if (!menu.isTopLevelMenu()) {
 558                 if(!(selectedPath.length > 0 &&
 559                      selectedPath[selectedPath.length-1] ==
 560                      menu.getPopupMenu())) {
 561                     if(menu.getDelay() == 0) {
 562                         appendPath(getPath(), menu.getPopupMenu());
 563                     } else {
 564                         manager.setSelectedPath(getPath());
 565                         setupPostTimer(menu);
 566                     }
 567                 }
 568             } else {
 569                 if(selectedPath.length > 0 &&
 570                    selectedPath[0] == menu.getParent()) {
 571                     MenuElement newPath[] = new MenuElement[3];
 572                     // A top level menu's parent is by definition
 573                     // a JMenuBar
 574                     newPath[0] = (MenuElement)menu.getParent();
 575                     newPath[1] = menu;
 576                     if (BasicPopupMenuUI.getLastPopup() != null) {
 577                         newPath[2] = menu.getPopupMenu();
 578                     }
 579                     manager.setSelectedPath(newPath);
 580                 }
 581             }
 582         }
 583         public void mouseExited(MouseEvent e) {
 584         }
 585 
 586         /**
 587          * Invoked when a mouse button is pressed on the menu and then dragged.
 588          * Delegates the mouse event to the MenuSelectionManager.
 589          *
 590          * @param e the mouse event
 591          * @see java.awt.event.MouseMotionListener#mouseDragged
 592          */
 593         public void mouseDragged(MouseEvent e) {
 594             JMenu menu = (JMenu)menuItem;
 595             if (!menu.isEnabled())
 596                 return;
 597             MenuSelectionManager.defaultManager().processMouseEvent(e);
 598         }
 599         public void mouseMoved(MouseEvent e) {
 600         }
 601 
 602 
 603         //
 604         // MenuDragHandler
 605         //
 606         public void menuDragMouseEntered(MenuDragMouseEvent e) {}
 607         public void menuDragMouseDragged(MenuDragMouseEvent e) {
 608             if (menuItem.isEnabled() == false)
 609                 return;
 610 
 611             MenuSelectionManager manager = e.getMenuSelectionManager();
 612             MenuElement path[] = e.getPath();
 613 
 614             Point p = e.getPoint();
 615             if(p.x >= 0 && p.x < menuItem.getWidth() &&
 616                p.y >= 0 && p.y < menuItem.getHeight()) {
 617                 JMenu menu = (JMenu)menuItem;
 618                 MenuElement selectedPath[] = manager.getSelectedPath();
 619                 if(!(selectedPath.length > 0 &&
 620                      selectedPath[selectedPath.length-1] ==
 621                      menu.getPopupMenu())) {
 622                     if(menu.isTopLevelMenu() ||
 623                        menu.getDelay() == 0  ||
 624                        e.getID() == MouseEvent.MOUSE_DRAGGED) {
 625                         appendPath(path, menu.getPopupMenu());
 626                     } else {
 627                         manager.setSelectedPath(path);
 628                         setupPostTimer(menu);
 629                     }
 630                 }
 631             } else if(e.getID() == MouseEvent.MOUSE_RELEASED) {
 632                 Component comp = manager.componentForPoint(e.getComponent(), e.getPoint());
 633                 if (comp == null)
 634                     manager.clearSelectedPath();
 635             }
 636 
 637         }
 638         public void menuDragMouseExited(MenuDragMouseEvent e) {}
 639         public void menuDragMouseReleased(MenuDragMouseEvent e) {}
 640 
 641         //
 642         // MenuKeyListener
 643         //
 644         /**
 645          * Open the Menu
 646          */
 647         public void menuKeyTyped(MenuKeyEvent e) {
 648             if (!crossMenuMnemonic && BasicPopupMenuUI.getLastPopup() != null) {
 649                 // when crossMenuMnemonic is not set, we don't open a toplevel
 650                 // menu if another toplevel menu is already open
 651                 return;
 652             }
 653 
 654             if (BasicPopupMenuUI.getPopups().size() != 0) {
 655                 //Fix 6939261: to return in case not on the main menu
 656                 //and has a pop-up.
 657                 //after return code will be handled in BasicPopupMenuUI.java
 658                 return;
 659             }
 660 
 661             char key = Character.toLowerCase((char)menuItem.getMnemonic());
 662             MenuElement path[] = e.getPath();
 663             if (key == Character.toLowerCase(e.getKeyChar())) {
 664                 JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu();
 665                 ArrayList<MenuElement> newList = new ArrayList<>(Arrays.asList(path));
 666                 newList.add(popupMenu);
 667                 MenuElement subs[] = popupMenu.getSubElements();
 668                 MenuElement sub =
 669                         BasicPopupMenuUI.findEnabledChild(subs, -1, true);
 670                 if(sub != null) {
 671                     newList.add(sub);
 672                 }
 673                 MenuSelectionManager manager = e.getMenuSelectionManager();
 674                 MenuElement newPath[] = new MenuElement[0];;
 675                 newPath = newList.toArray(newPath);
 676                 manager.setSelectedPath(newPath);
 677                 e.consume();
 678             }
 679         }
 680 
 681         public void menuKeyPressed(MenuKeyEvent e) {}
 682         public void menuKeyReleased(MenuKeyEvent e) {}
 683     }
 684 }
--- EOF ---