📄 basicpopupmenuui.java
字号:
if (!(ev instanceof MouseEvent)) { // We are interested in MouseEvents only return; } MouseEvent me = (MouseEvent) ev; Component src = me.getComponent(); switch (me.getID()) { case MouseEvent.MOUSE_PRESSED: if (isInPopup(src) || (src instanceof JMenu && ((JMenu)src).isSelected())) { return; } if (!(src instanceof JComponent) || ! (((JComponent)src).getClientProperty("doNotCancelPopup") == BasicComboBoxUI.HIDE_POPUP_KEY)) { // Cancel popup only if this property was not set. // If this property is set to TRUE component wants // to deal with this event by himself. cancelPopupMenu(); // Ask UIManager about should we consume event that closes // popup. This made to match native apps behaviour. boolean consumeEvent = UIManager.getBoolean("PopupMenu.consumeEventOnClose"); // Consume the event so that normal processing stops. if(consumeEvent && !(src instanceof MenuElement)) { me.consume(); } } break; case MouseEvent.MOUSE_RELEASED: if(!(src instanceof MenuElement)) { // Do not forward event to MSM, let component handle it if (isInPopup(src)) { break; } } if(src instanceof JMenu || !(src instanceof JMenuItem)) { MenuSelectionManager.defaultManager(). processMouseEvent(me); } break; case MouseEvent.MOUSE_DRAGGED: if(!(src instanceof MenuElement)) { // For the MOUSE_DRAGGED event the src is // the Component in which mouse button was pressed. // If the src is in popupMenu, // do not forward event to MSM, let component handle it. if (isInPopup(src)) { break; } } MenuSelectionManager.defaultManager(). processMouseEvent(me); break; case MouseEvent.MOUSE_WHEEL: if (isInPopup(src)) { return; } cancelPopupMenu(); break; } } boolean isInPopup(Component src) { for (Component c=src; c!=null; c=c.getParent()) { if (c instanceof Applet || c instanceof Window) { break; } else if (c instanceof JPopupMenu) { return true; } } return false; } void cancelPopupMenu() { JPopupMenu firstPopup = (JPopupMenu)getFirstPopup(); // 4234793: This action should call firePopupMenuCanceled but it's // a protected method. The real solution could be to make // firePopupMenuCanceled public and call it directly. List popups = getPopups(); Iterator iter = popups.iterator(); while (iter.hasNext()) { JPopupMenu popup = (JPopupMenu)iter.next(); popup.putClientProperty("JPopupMenu.firePopupMenuCanceled", Boolean.TRUE); } MenuSelectionManager.defaultManager().clearSelectedPath(); } public void componentResized(ComponentEvent e) { cancelPopupMenu(); } public void componentMoved(ComponentEvent e) { cancelPopupMenu(); } public void componentShown(ComponentEvent e) { cancelPopupMenu(); } public void componentHidden(ComponentEvent e) { cancelPopupMenu(); } public void windowClosing(WindowEvent e) { cancelPopupMenu(); } public void windowClosed(WindowEvent e) { cancelPopupMenu(); } public void windowIconified(WindowEvent e) { cancelPopupMenu(); } public void windowDeactivated(WindowEvent e) { cancelPopupMenu(); } public void windowOpened(WindowEvent e) {} public void windowDeiconified(WindowEvent e) {} public void windowActivated(WindowEvent e) {} } /** * This helper is added to MenuSelectionManager as a ChangeListener to * listen to menu selection changes. When a menu is activated, it passes * focus to its parent JRootPane, and installs an ActionMap/InputMap pair * on that JRootPane. Those maps are necessary in order for menu * navigation to work. When menu is being deactivated, it restores focus * to the component that has had it before menu activation, and uninstalls * the maps. * This helper is also installed as a KeyListener on root pane when menu * is active. It forwards key events to MenuSelectionManager for mnemonic * keys handling. */ static class MenuKeyboardHelper implements ChangeListener, KeyListener { private Component lastFocused = null; private MenuElement[] lastPathSelected = new MenuElement[0]; private JPopupMenu lastPopup; private JRootPane invokerRootPane; private ActionMap menuActionMap = getActionMap(); private InputMap menuInputMap; private boolean focusTraversalKeysEnabled; /* * Fix for 4213634 * If this is false, KEY_TYPED and KEY_RELEASED events are NOT * processed. This is needed to avoid activating a menuitem when * the menu and menuitem share the same mnemonic. */ private boolean receivedKeyPressed = false; void removeItems() { if (lastFocused != null) { if(!lastFocused.requestFocusInWindow()) { // Workarounr for 4810575. // If lastFocused is not in currently focused window // requestFocusInWindow will fail. In this case we must // request focus by requestFocus() if it was not // transferred from our popup. Window cfw = KeyboardFocusManager .getCurrentKeyboardFocusManager() .getFocusedWindow(); if(cfw != null && "###focusableSwingPopup###".equals(cfw.getName())) { lastFocused.requestFocus(); } } lastFocused = null; } if (invokerRootPane != null) { invokerRootPane.removeKeyListener(this); invokerRootPane.setFocusTraversalKeysEnabled(focusTraversalKeysEnabled); removeUIInputMap(invokerRootPane, menuInputMap); removeUIActionMap(invokerRootPane, menuActionMap); invokerRootPane = null; } receivedKeyPressed = false; } private FocusListener rootPaneFocusListener = new FocusAdapter() { public void focusGained(FocusEvent ev) { Component opposite = ev.getOppositeComponent(); if (opposite != null) { lastFocused = opposite; } ev.getComponent().removeFocusListener(this); } }; /** * Return the last JPopupMenu in <code>path</code>, * or <code>null</code> if none found */ JPopupMenu getActivePopup(MenuElement[] path) { for (int i=path.length-1; i>=0; i--) { MenuElement elem = path[i]; if (elem instanceof JPopupMenu) { return (JPopupMenu)elem; } } return null; } void addUIInputMap(JComponent c, InputMap map) { InputMap lastNonUI = null; InputMap parent = c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); while (parent != null && !(parent instanceof UIResource)) { lastNonUI = parent; parent = parent.getParent(); } if (lastNonUI == null) { c.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, map); } else { lastNonUI.setParent(map); } map.setParent(parent); } void addUIActionMap(JComponent c, ActionMap map) { ActionMap lastNonUI = null; ActionMap parent = c.getActionMap(); while (parent != null && !(parent instanceof UIResource)) { lastNonUI = parent; parent = parent.getParent(); } if (lastNonUI == null) { c.setActionMap(map); } else { lastNonUI.setParent(map); } map.setParent(parent); } void removeUIInputMap(JComponent c, InputMap map) { InputMap im = null; InputMap parent = c.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); while (parent != null) { if (parent == map) { if (im == null) { c.setInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, map.getParent()); } else { im.setParent(map.getParent()); } break; } im = parent; parent = parent.getParent(); } } void removeUIActionMap(JComponent c, ActionMap map) { ActionMap im = null; ActionMap parent = c.getActionMap(); while (parent != null) { if (parent == map) { if (im == null) { c.setActionMap(map.getParent()); } else { im.setParent(map.getParent()); } break; } im = parent; parent = parent.getParent(); } } public void stateChanged(ChangeEvent ev) { if (!(UIManager.getLookAndFeel() instanceof BasicLookAndFeel)) { uninstall(); return; } MenuSelectionManager msm = (MenuSelectionManager)ev.getSource(); MenuElement[] p = msm.getSelectedPath(); JPopupMenu popup = getActivePopup(p); if (popup != null && !popup.isFocusable()) { // Do nothing for non-focusable popups return; } if (lastPathSelected.length != 0 && p.length != 0 ) { if (!checkInvokerEqual(p[0],lastPathSelected[0])) { removeItems(); lastPathSelected = new MenuElement[0]; } } if (lastPathSelected.length == 0 && p.length > 0) { // menu posted JComponent invoker; if (popup == null) { if (p.length == 2 && p[0] instanceof JMenuBar && p[1] instanceof JMenu) { // a menu has been selected but not open invoker = (JComponent)p[1]; popup = ((JMenu)invoker).getPopupMenu(); } else { return; } } else { Component c = popup.getInvoker(); if(c instanceof JFrame) { invoker = ((JFrame)c).getRootPane(); } else if(c instanceof JDialog) { invoker = ((JDialog)c).getRootPane(); } else if(c instanceof JApplet) { invoker = ((JApplet)c).getRootPane(); } else { while (!(c instanceof JComponent)) { if (c == null) { return; } c = c.getParent(); } invoker = (JComponent)c; } } // remember current focus owner lastFocused = KeyboardFocusManager. getCurrentKeyboardFocusManager().getFocusOwner(); // request focus on root pane and install keybindings // used for menu navigation invokerRootPane = SwingUtilities.getRootPane(invoker); if (invokerRootPane != null) { invokerRootPane.addFocusListener(rootPaneFocusListener); invokerRootPane.requestFocus(true); invokerRootPane.addKeyListener(this); focusTraversalKeysEnabled = invokerRootPane. getFocusTraversalKeysEnabled(); invokerRootPane.setFocusTraversalKeysEnabled(false); menuInputMap = getInputMap(popup, invokerRootPane); addUIInputMap(invokerRootPane, menuInputMap); addUIActionMap(invokerRootPane, menuActionMap); } } else if (lastPathSelected.length != 0 && p.length == 0) { // menu hidden -- return focus to where it had been before // and uninstall menu keybindings removeItems(); } else { if (popup != lastPopup) { receivedKeyPressed = false; } } // Remember the last path selected lastPathSelected = p; lastPopup = popup; } public void keyPressed(KeyEvent ev) { receivedKeyPressed = true; MenuSelectionManager.defaultManager().processKeyEvent(ev); } public void keyReleased(KeyEvent ev) { if (receivedKeyPressed) { receivedKeyPressed = false; MenuSelectionManager.defaultManager().processKeyEvent(ev); } } public void keyTyped(KeyEvent ev) { if (receivedKeyPressed) { MenuSelectionManager.defaultManager().processKeyEvent(ev); } } void uninstall() { synchronized (MENU_KEYBOARD_HELPER_KEY) { MenuSelectionManager.defaultManager().removeChangeListener(this); AppContext.getAppContext().remove(MENU_KEYBOARD_HELPER_KEY); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -