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
236 if (((JMenu)menuItem).isTopLevelMenu()) {
237 Dimension d = c.getPreferredSize();
238 return new Dimension(d.width, Short.MAX_VALUE);
239 }
240 return null;
241 }
242
243 /**
244 * Sets timer to the {@code menu}.
245 *
246 * @param menu an instance of {@code JMenu}.
247 */
248 protected void setupPostTimer(JMenu menu) {
249 Timer timer = new Timer(menu.getDelay(), new Actions(
250 Actions.SELECT, menu,false));
251 timer.setRepeats(false);
252 timer.start();
253 }
254
255 private static void appendPath(MenuElement[] path, MenuElement elem) {
256 MenuElement newPath[] = new MenuElement[path.length+1];
257 System.arraycopy(path, 0, newPath, 0, path.length);
258 newPath[path.length] = elem;
259 MenuSelectionManager.defaultManager().setSelectedPath(newPath);
260 }
261
262 private static class Actions extends UIAction {
263 private static final String SELECT = "selectMenu";
264
265 // NOTE: This will be null if the action is registered in the
266 // ActionMap. For the timer use it will be non-null.
267 private JMenu menu;
268 private boolean force=false;
269
270 Actions(String key, JMenu menu, boolean shouldForce) {
271 super(key);
272 this.menu = menu;
273 this.force = shouldForce;
274 }
275
276 private JMenu getMenu(ActionEvent e) {
277 if (e.getSource() instanceof JMenu) {
278 return (JMenu)e.getSource();
279 }
280 return menu;
281 }
282
283 public void actionPerformed(ActionEvent e) {
284 JMenu menu = getMenu(e);
285 if (!crossMenuMnemonic) {
286 JPopupMenu pm = BasicPopupMenuUI.getLastPopup();
287 if (pm != null && pm != menu.getParent()) {
288 return;
289 }
290 }
291
292 final MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
293 if(force) {
294 Container cnt = menu.getParent();
295 if(cnt != null && cnt instanceof JMenuBar) {
296 MenuElement me[];
297 MenuElement subElements[];
298
299 subElements = menu.getPopupMenu().getSubElements();
300 if(subElements.length > 0) {
301 me = new MenuElement[4];
302 me[0] = (MenuElement) cnt;
303 me[1] = menu;
304 me[2] = menu.getPopupMenu();
305 me[3] = subElements[0];
306 } else {
307 me = new MenuElement[3];
308 me[0] = (MenuElement)cnt;
309 me[1] = menu;
310 me[2] = menu.getPopupMenu();
311 }
312 defaultManager.setSelectedPath(me);
313 }
314 } else {
315 MenuElement path[] = defaultManager.getSelectedPath();
316 if(path.length > 0 && path[path.length-1] == menu) {
317 appendPath(path, menu.getPopupMenu());
318 }
319 }
320 }
321
322 @Override
323 public boolean accept(Object c) {
324 if (c instanceof JMenu) {
325 return ((JMenu)c).isEnabled();
326 }
327 return true;
328 }
329 }
330
331 /*
332 * Set the background color depending on whether this is a toplevel menu
333 * in a menubar or a submenu of another menu.
334 */
335 private void updateDefaultBackgroundColor() {
486 /**
487 * Invoked when the mouse has been clicked on the menu. This
488 * method clears or sets the selection path of the
489 * MenuSelectionManager.
490 *
491 * @param e the mouse event
492 */
493 public void mousePressed(MouseEvent e) {
494 JMenu menu = (JMenu)menuItem;
495 if (!menu.isEnabled())
496 return;
497
498 MenuSelectionManager manager =
499 MenuSelectionManager.defaultManager();
500 if(menu.isTopLevelMenu()) {
501 if(menu.isSelected() && menu.getPopupMenu().isShowing()) {
502 manager.clearSelectedPath();
503 } else {
504 Container cnt = menu.getParent();
505 if(cnt != null && cnt instanceof JMenuBar) {
506 MenuElement me[] = new MenuElement[2];
507 me[0]=(MenuElement)cnt;
508 me[1]=menu;
509 manager.setSelectedPath(me);
510 }
511 }
512 }
513
514 MenuElement selectedPath[] = manager.getSelectedPath();
515 if (selectedPath.length > 0 &&
516 selectedPath[selectedPath.length-1] != menu.getPopupMenu()) {
517
518 if(menu.isTopLevelMenu() ||
519 menu.getDelay() == 0) {
520 appendPath(selectedPath, menu.getPopupMenu());
521 } else {
522 setupPostTimer(menu);
523 }
524 }
525 }
526
527 /**
528 * Invoked when the mouse has been released on the menu. Delegates the
529 * mouse event to the MenuSelectionManager.
530 *
531 * @param e the mouse event
532 */
533 public void mouseReleased(MouseEvent e) {
534 JMenu menu = (JMenu)menuItem;
542 }
543
544 /**
545 * Invoked when the cursor enters the menu. This method sets the selected
546 * path for the MenuSelectionManager and handles the case
547 * in which a menu item is used to pop up an additional menu, as in a
548 * hierarchical menu system.
549 *
550 * @param e the mouse event; not used
551 */
552 public void mouseEntered(MouseEvent e) {
553 JMenu menu = (JMenu)menuItem;
554 // only disable the menu highlighting if it's disabled and the property isn't
555 // true. This allows disabled rollovers to work in WinL&F
556 if (!menu.isEnabled() && !UIManager.getBoolean("MenuItem.disabledAreNavigable")) {
557 return;
558 }
559
560 MenuSelectionManager manager =
561 MenuSelectionManager.defaultManager();
562 MenuElement selectedPath[] = manager.getSelectedPath();
563 if (!menu.isTopLevelMenu()) {
564 if(!(selectedPath.length > 0 &&
565 selectedPath[selectedPath.length-1] ==
566 menu.getPopupMenu())) {
567 if(menu.getDelay() == 0) {
568 appendPath(getPath(), menu.getPopupMenu());
569 } else {
570 manager.setSelectedPath(getPath());
571 setupPostTimer(menu);
572 }
573 }
574 } else {
575 if(selectedPath.length > 0 &&
576 selectedPath[0] == menu.getParent()) {
577 MenuElement newPath[] = new MenuElement[3];
578 // A top level menu's parent is by definition
579 // a JMenuBar
580 newPath[0] = (MenuElement)menu.getParent();
581 newPath[1] = menu;
582 if (BasicPopupMenuUI.getLastPopup() != null) {
583 newPath[2] = menu.getPopupMenu();
584 }
585 manager.setSelectedPath(newPath);
586 }
587 }
588 }
589 public void mouseExited(MouseEvent e) {
590 }
591
592 /**
593 * Invoked when a mouse button is pressed on the menu and then dragged.
594 * Delegates the mouse event to the MenuSelectionManager.
595 *
596 * @param e the mouse event
597 * @see java.awt.event.MouseMotionListener#mouseDragged
598 */
599 public void mouseDragged(MouseEvent e) {
600 JMenu menu = (JMenu)menuItem;
601 if (!menu.isEnabled())
602 return;
603 MenuSelectionManager.defaultManager().processMouseEvent(e);
604 }
605 public void mouseMoved(MouseEvent e) {
606 }
607
608
609 //
610 // MenuDragHandler
611 //
612 public void menuDragMouseEntered(MenuDragMouseEvent e) {}
613 public void menuDragMouseDragged(MenuDragMouseEvent e) {
614 if (menuItem.isEnabled() == false)
615 return;
616
617 MenuSelectionManager manager = e.getMenuSelectionManager();
618 MenuElement path[] = e.getPath();
619
620 Point p = e.getPoint();
621 if(p.x >= 0 && p.x < menuItem.getWidth() &&
622 p.y >= 0 && p.y < menuItem.getHeight()) {
623 JMenu menu = (JMenu)menuItem;
624 MenuElement selectedPath[] = manager.getSelectedPath();
625 if(!(selectedPath.length > 0 &&
626 selectedPath[selectedPath.length-1] ==
627 menu.getPopupMenu())) {
628 if(menu.isTopLevelMenu() ||
629 menu.getDelay() == 0 ||
630 e.getID() == MouseEvent.MOUSE_DRAGGED) {
631 appendPath(path, menu.getPopupMenu());
632 } else {
633 manager.setSelectedPath(path);
634 setupPostTimer(menu);
635 }
636 }
637 } else if(e.getID() == MouseEvent.MOUSE_RELEASED) {
638 Component comp = manager.componentForPoint(e.getComponent(), e.getPoint());
639 if (comp == null)
640 manager.clearSelectedPath();
641 }
642
643 }
644 public void menuDragMouseExited(MenuDragMouseEvent e) {}
648 // MenuKeyListener
649 //
650 /**
651 * Open the Menu
652 */
653 public void menuKeyTyped(MenuKeyEvent e) {
654 if (!crossMenuMnemonic && BasicPopupMenuUI.getLastPopup() != null) {
655 // when crossMenuMnemonic is not set, we don't open a toplevel
656 // menu if another toplevel menu is already open
657 return;
658 }
659
660 if (BasicPopupMenuUI.getPopups().size() != 0) {
661 //Fix 6939261: to return in case not on the main menu
662 //and has a pop-up.
663 //after return code will be handled in BasicPopupMenuUI.java
664 return;
665 }
666
667 char key = Character.toLowerCase((char)menuItem.getMnemonic());
668 MenuElement path[] = e.getPath();
669 if (key == Character.toLowerCase(e.getKeyChar())) {
670 JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu();
671 ArrayList<MenuElement> newList = new ArrayList<>(Arrays.asList(path));
672 newList.add(popupMenu);
673 MenuElement subs[] = popupMenu.getSubElements();
674 MenuElement sub =
675 BasicPopupMenuUI.findEnabledChild(subs, -1, true);
676 if(sub != null) {
677 newList.add(sub);
678 }
679 MenuSelectionManager manager = e.getMenuSelectionManager();
680 MenuElement newPath[] = new MenuElement[0];;
681 newPath = newList.toArray(newPath);
682 manager.setSelectedPath(newPath);
683 e.consume();
684 }
685 }
686
687 public void menuKeyPressed(MenuKeyEvent e) {}
688 public void menuKeyReleased(MenuKeyEvent e) {}
689 }
690 }
|
1 /*
2 * Copyright (c) 1997, 2018, 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
236 if (((JMenu)menuItem).isTopLevelMenu()) {
237 Dimension d = c.getPreferredSize();
238 return new Dimension(d.width, Short.MAX_VALUE);
239 }
240 return null;
241 }
242
243 /**
244 * Sets timer to the {@code menu}.
245 *
246 * @param menu an instance of {@code JMenu}.
247 */
248 protected void setupPostTimer(JMenu menu) {
249 Timer timer = new Timer(menu.getDelay(), new Actions(
250 Actions.SELECT, menu,false));
251 timer.setRepeats(false);
252 timer.start();
253 }
254
255 private static void appendPath(MenuElement[] path, MenuElement elem) {
256 MenuElement[] newPath = new MenuElement[path.length+1];
257 System.arraycopy(path, 0, newPath, 0, path.length);
258 newPath[path.length] = elem;
259 MenuSelectionManager.defaultManager().setSelectedPath(newPath);
260 }
261
262 private static class Actions extends UIAction {
263 private static final String SELECT = "selectMenu";
264
265 // NOTE: This will be null if the action is registered in the
266 // ActionMap. For the timer use it will be non-null.
267 private JMenu menu;
268 private boolean force=false;
269
270 Actions(String key, JMenu menu, boolean shouldForce) {
271 super(key);
272 this.menu = menu;
273 this.force = shouldForce;
274 }
275
276 private JMenu getMenu(ActionEvent e) {
277 if (e.getSource() instanceof JMenu) {
278 return (JMenu)e.getSource();
279 }
280 return menu;
281 }
282
283 public void actionPerformed(ActionEvent e) {
284 JMenu menu = getMenu(e);
285 if (!crossMenuMnemonic) {
286 JPopupMenu pm = BasicPopupMenuUI.getLastPopup();
287 if (pm != null && pm != menu.getParent()) {
288 return;
289 }
290 }
291
292 final MenuSelectionManager defaultManager = MenuSelectionManager.defaultManager();
293 if(force) {
294 Container cnt = menu.getParent();
295 if(cnt != null && cnt instanceof JMenuBar) {
296 MenuElement[] me;
297 MenuElement[] subElements;
298
299 subElements = menu.getPopupMenu().getSubElements();
300 if(subElements.length > 0) {
301 me = new MenuElement[4];
302 me[0] = (MenuElement) cnt;
303 me[1] = menu;
304 me[2] = menu.getPopupMenu();
305 me[3] = subElements[0];
306 } else {
307 me = new MenuElement[3];
308 me[0] = (MenuElement)cnt;
309 me[1] = menu;
310 me[2] = menu.getPopupMenu();
311 }
312 defaultManager.setSelectedPath(me);
313 }
314 } else {
315 MenuElement[] path = defaultManager.getSelectedPath();
316 if(path.length > 0 && path[path.length-1] == menu) {
317 appendPath(path, menu.getPopupMenu());
318 }
319 }
320 }
321
322 @Override
323 public boolean accept(Object c) {
324 if (c instanceof JMenu) {
325 return ((JMenu)c).isEnabled();
326 }
327 return true;
328 }
329 }
330
331 /*
332 * Set the background color depending on whether this is a toplevel menu
333 * in a menubar or a submenu of another menu.
334 */
335 private void updateDefaultBackgroundColor() {
486 /**
487 * Invoked when the mouse has been clicked on the menu. This
488 * method clears or sets the selection path of the
489 * MenuSelectionManager.
490 *
491 * @param e the mouse event
492 */
493 public void mousePressed(MouseEvent e) {
494 JMenu menu = (JMenu)menuItem;
495 if (!menu.isEnabled())
496 return;
497
498 MenuSelectionManager manager =
499 MenuSelectionManager.defaultManager();
500 if(menu.isTopLevelMenu()) {
501 if(menu.isSelected() && menu.getPopupMenu().isShowing()) {
502 manager.clearSelectedPath();
503 } else {
504 Container cnt = menu.getParent();
505 if(cnt != null && cnt instanceof JMenuBar) {
506 MenuElement[] me = new MenuElement[2];
507 me[0]=(MenuElement)cnt;
508 me[1]=menu;
509 manager.setSelectedPath(me);
510 }
511 }
512 }
513
514 MenuElement[] selectedPath = manager.getSelectedPath();
515 if (selectedPath.length > 0 &&
516 selectedPath[selectedPath.length-1] != menu.getPopupMenu()) {
517
518 if(menu.isTopLevelMenu() ||
519 menu.getDelay() == 0) {
520 appendPath(selectedPath, menu.getPopupMenu());
521 } else {
522 setupPostTimer(menu);
523 }
524 }
525 }
526
527 /**
528 * Invoked when the mouse has been released on the menu. Delegates the
529 * mouse event to the MenuSelectionManager.
530 *
531 * @param e the mouse event
532 */
533 public void mouseReleased(MouseEvent e) {
534 JMenu menu = (JMenu)menuItem;
542 }
543
544 /**
545 * Invoked when the cursor enters the menu. This method sets the selected
546 * path for the MenuSelectionManager and handles the case
547 * in which a menu item is used to pop up an additional menu, as in a
548 * hierarchical menu system.
549 *
550 * @param e the mouse event; not used
551 */
552 public void mouseEntered(MouseEvent e) {
553 JMenu menu = (JMenu)menuItem;
554 // only disable the menu highlighting if it's disabled and the property isn't
555 // true. This allows disabled rollovers to work in WinL&F
556 if (!menu.isEnabled() && !UIManager.getBoolean("MenuItem.disabledAreNavigable")) {
557 return;
558 }
559
560 MenuSelectionManager manager =
561 MenuSelectionManager.defaultManager();
562 MenuElement[] selectedPath = manager.getSelectedPath();
563 if (!menu.isTopLevelMenu()) {
564 if(!(selectedPath.length > 0 &&
565 selectedPath[selectedPath.length-1] ==
566 menu.getPopupMenu())) {
567 if(menu.getDelay() == 0) {
568 appendPath(getPath(), menu.getPopupMenu());
569 } else {
570 manager.setSelectedPath(getPath());
571 setupPostTimer(menu);
572 }
573 }
574 } else {
575 if(selectedPath.length > 0 &&
576 selectedPath[0] == menu.getParent()) {
577 MenuElement[] newPath = new MenuElement[3];
578 // A top level menu's parent is by definition
579 // a JMenuBar
580 newPath[0] = (MenuElement)menu.getParent();
581 newPath[1] = menu;
582 if (BasicPopupMenuUI.getLastPopup() != null) {
583 newPath[2] = menu.getPopupMenu();
584 }
585 manager.setSelectedPath(newPath);
586 }
587 }
588 }
589 public void mouseExited(MouseEvent e) {
590 }
591
592 /**
593 * Invoked when a mouse button is pressed on the menu and then dragged.
594 * Delegates the mouse event to the MenuSelectionManager.
595 *
596 * @param e the mouse event
597 * @see java.awt.event.MouseMotionListener#mouseDragged
598 */
599 public void mouseDragged(MouseEvent e) {
600 JMenu menu = (JMenu)menuItem;
601 if (!menu.isEnabled())
602 return;
603 MenuSelectionManager.defaultManager().processMouseEvent(e);
604 }
605 public void mouseMoved(MouseEvent e) {
606 }
607
608
609 //
610 // MenuDragHandler
611 //
612 public void menuDragMouseEntered(MenuDragMouseEvent e) {}
613 public void menuDragMouseDragged(MenuDragMouseEvent e) {
614 if (menuItem.isEnabled() == false)
615 return;
616
617 MenuSelectionManager manager = e.getMenuSelectionManager();
618 MenuElement[] path = e.getPath();
619
620 Point p = e.getPoint();
621 if(p.x >= 0 && p.x < menuItem.getWidth() &&
622 p.y >= 0 && p.y < menuItem.getHeight()) {
623 JMenu menu = (JMenu)menuItem;
624 MenuElement[] selectedPath = manager.getSelectedPath();
625 if(!(selectedPath.length > 0 &&
626 selectedPath[selectedPath.length-1] ==
627 menu.getPopupMenu())) {
628 if(menu.isTopLevelMenu() ||
629 menu.getDelay() == 0 ||
630 e.getID() == MouseEvent.MOUSE_DRAGGED) {
631 appendPath(path, menu.getPopupMenu());
632 } else {
633 manager.setSelectedPath(path);
634 setupPostTimer(menu);
635 }
636 }
637 } else if(e.getID() == MouseEvent.MOUSE_RELEASED) {
638 Component comp = manager.componentForPoint(e.getComponent(), e.getPoint());
639 if (comp == null)
640 manager.clearSelectedPath();
641 }
642
643 }
644 public void menuDragMouseExited(MenuDragMouseEvent e) {}
648 // MenuKeyListener
649 //
650 /**
651 * Open the Menu
652 */
653 public void menuKeyTyped(MenuKeyEvent e) {
654 if (!crossMenuMnemonic && BasicPopupMenuUI.getLastPopup() != null) {
655 // when crossMenuMnemonic is not set, we don't open a toplevel
656 // menu if another toplevel menu is already open
657 return;
658 }
659
660 if (BasicPopupMenuUI.getPopups().size() != 0) {
661 //Fix 6939261: to return in case not on the main menu
662 //and has a pop-up.
663 //after return code will be handled in BasicPopupMenuUI.java
664 return;
665 }
666
667 char key = Character.toLowerCase((char)menuItem.getMnemonic());
668 MenuElement[] path = e.getPath();
669 if (key == Character.toLowerCase(e.getKeyChar())) {
670 JPopupMenu popupMenu = ((JMenu)menuItem).getPopupMenu();
671 ArrayList<MenuElement> newList = new ArrayList<>(Arrays.asList(path));
672 newList.add(popupMenu);
673 MenuElement[] subs = popupMenu.getSubElements();
674 MenuElement sub =
675 BasicPopupMenuUI.findEnabledChild(subs, -1, true);
676 if(sub != null) {
677 newList.add(sub);
678 }
679 MenuSelectionManager manager = e.getMenuSelectionManager();
680 MenuElement[] newPath = new MenuElement[0];;
681 newPath = newList.toArray(newPath);
682 manager.setSelectedPath(newPath);
683 e.consume();
684 }
685 }
686
687 public void menuKeyPressed(MenuKeyEvent e) {}
688 public void menuKeyReleased(MenuKeyEvent e) {}
689 }
690 }
|