📄 basicpopupmenuui.java
字号:
path[1] = (MenuElement) comps[0]; manager.setSelectedPath(path); } } } } /** * ComponentListener that listens to Component Events fired by the top - * level window to which popup menu belongs. If top-level window was * resized, moved or hidded then popup menu will be hidded and selected * path of current menu hierarchy will be set to null. */ private class TopWindowListener implements ComponentListener { /** * This method is invoked when top-level window is resized. This method * closes current menu hierarchy. * * @param e The ComponentEvent */ public void componentResized(ComponentEvent e) { MenuSelectionManager manager = MenuSelectionManager.defaultManager(); manager.clearSelectedPath(); } /** * This method is invoked when top-level window is moved. This method * closes current menu hierarchy. * * @param e The ComponentEvent */ public void componentMoved(ComponentEvent e) { MenuSelectionManager manager = MenuSelectionManager.defaultManager(); manager.clearSelectedPath(); } /** * This method is invoked when top-level window is shown This method * does nothing by default. * * @param e The ComponentEvent */ public void componentShown(ComponentEvent e) { MenuSelectionManager manager = MenuSelectionManager.defaultManager(); manager.clearSelectedPath(); } /** * This method is invoked when top-level window is hidden This method * closes current menu hierarchy. * * @param e The ComponentEvent */ public void componentHidden(ComponentEvent e) { MenuSelectionManager manager = MenuSelectionManager.defaultManager(); manager.clearSelectedPath(); } } /** * MouseInputHandler listens to all mouse events originated in the root * container. This class is responsible for closing menu hierarchy when the * user presses mouse over any component that do not belong to the current * menu hierarchy. This is acomplished by interrupting all mouse event in * the glass pane and checking if other component was pressed while menu * was open, before redestributing events further to intended components */ private class MouseInputHandler implements MouseInputListener { private JLayeredPane layeredPane; private Container glassPane; private Cursor nativeCursor; private transient Component mouseEventTarget; private transient Component pressedComponent; private transient Component lastComponentEntered; private transient Component tempComponent; private transient int pressCount; /** * Creates a new MouseInputHandler object. * * @param c the top most root container */ public MouseInputHandler(RootPaneContainer c) { layeredPane = c.getLayeredPane(); glassPane = (Container) c.getGlassPane(); } /** * Handles mouse clicked event * * @param e Mouse event */ public void mouseClicked(MouseEvent e) { handleEvent(e); } /** * Handles mouseDragged event * * @param e MouseEvent */ public void mouseDragged(MouseEvent e) { handleEvent(e); } /** * Handles mouseEntered event * * @param e MouseEvent */ public void mouseEntered(MouseEvent e) { handleEvent(e); } /** * Handles mouseExited event * * @param e MouseEvent */ public void mouseExited(MouseEvent e) { handleEvent(e); } /** * Handles mouse moved event * * @param e MouseEvent */ public void mouseMoved(MouseEvent e) { handleEvent(e); } /** * Handles mouse pressed event * * @param e MouseEvent */ public void mousePressed(MouseEvent e) { handleEvent(e); } /** * Handles mouse released event * * @param e MouseEvent */ public void mouseReleased(MouseEvent e) { handleEvent(e); } /* * This method determines component that was intended to received mouse * event, before it was interrupted within the glass pane. This method * also redispatches mouse entered and mouse exited events to the * appropriate components. This code is slightly modified code from * Container.LightweightDispatcher class, which is private inside * Container class and cannot be used here. */ public void acquireComponentForMouseEvent(MouseEvent me) { int x = me.getX(); int y = me.getY(); // Find the candidate which should receive this event. Component parent = layeredPane; Component candidate = null; Point p = me.getPoint(); while ((candidate == null) && (parent != null)) { p = SwingUtilities.convertPoint(glassPane, p.x, p.y, parent); candidate = SwingUtilities.getDeepestComponentAt(parent, p.x, p.y); if (candidate == null) { p = SwingUtilities.convertPoint(parent, p.x, p.y, parent.getParent()); parent = parent.getParent(); } } // If the only candidate we found was the native container itself, // don't dispatch any event at all. We only care about the lightweight // children here. if (candidate == layeredPane) candidate = null; // If our candidate is new, inform the old target we're leaving. if ((lastComponentEntered != null) && lastComponentEntered.isShowing() && (lastComponentEntered != candidate)) { // Old candidate could have been removed from // the layeredPane so we check first. if (SwingUtilities.isDescendingFrom(lastComponentEntered, layeredPane)) { Point tp = SwingUtilities.convertPoint(layeredPane, x, y, lastComponentEntered); MouseEvent exited = new MouseEvent(lastComponentEntered, MouseEvent.MOUSE_EXITED, me.getWhen(), me.getModifiersEx(), tp.x, tp.y, me.getClickCount(), me.isPopupTrigger(), me.getButton()); tempComponent = lastComponentEntered; lastComponentEntered = null; tempComponent.dispatchEvent(exited); } lastComponentEntered = null; } // If we have a candidate, maybe enter it. if (candidate != null) { mouseEventTarget = candidate; if (candidate.isLightweight() && candidate.isShowing() && (candidate != layeredPane) && (candidate != lastComponentEntered)) { lastComponentEntered = mouseEventTarget; Point cp = SwingUtilities.convertPoint(layeredPane, x, y, lastComponentEntered); MouseEvent entered = new MouseEvent(lastComponentEntered, MouseEvent.MOUSE_ENTERED, me.getWhen(), me.getModifiersEx(), cp.x, cp.y, me.getClickCount(), me.isPopupTrigger(), me.getButton()); lastComponentEntered.dispatchEvent(entered); } } if ((me.getID() == MouseEvent.MOUSE_RELEASED) || ((me.getID() == MouseEvent.MOUSE_PRESSED) && (pressCount > 0)) || (me.getID() == MouseEvent.MOUSE_DRAGGED)) { // If any of the following events occur while a button is held down, // they should be dispatched to the same component to which the // original MOUSE_PRESSED event was dispatched: // - MOUSE_RELEASED // - MOUSE_PRESSED: another button pressed while the first is held down // - MOUSE_DRAGGED if (SwingUtilities.isDescendingFrom(pressedComponent, layeredPane)) mouseEventTarget = pressedComponent; else if (me.getID() == MouseEvent.MOUSE_CLICKED) { // Don't dispatch CLICKED events whose target is not the same as the // target for the original PRESSED event. if (candidate != pressedComponent) mouseEventTarget = null; else if (pressCount == 0) pressedComponent = null; } } } /* * This method handles mouse events interrupted by glassPane. It * redispatches the mouse events appropriately to the intended components. * The code in this method is also taken from * Container.LightweightDispatcher class. The code is slightly modified * to handle the case when mouse is released over non-menu component. In * this case this method closes current menu hierarchy before * redispatching the event further. */ public void handleEvent(AWTEvent e) { if (e instanceof MouseEvent) { MouseEvent me = (MouseEvent) e; acquireComponentForMouseEvent(me); // Avoid dispatching ENTERED and EXITED events twice. if (mouseEventTarget != null && mouseEventTarget.isShowing() && (e.getID() != MouseEvent.MOUSE_ENTERED) && (e.getID() != MouseEvent.MOUSE_EXITED)) { MouseEvent newEvt = SwingUtilities.convertMouseEvent(glassPane, me, mouseEventTarget); mouseEventTarget.dispatchEvent(newEvt); // If mouse was clicked over the component that is not part // of menu hierarchy,then must close the menu hierarchy */ if (e.getID() == MouseEvent.MOUSE_RELEASED) { boolean partOfMenuHierarchy = false; MenuSelectionManager manager = MenuSelectionManager .defaultManager(); partOfMenuHierarchy = manager.isComponentPartOfCurrentMenu(mouseEventTarget); if (! partOfMenuHierarchy) manager.clearSelectedPath(); } switch (e.getID()) { case MouseEvent.MOUSE_PRESSED: if (pressCount++ == 0) pressedComponent = mouseEventTarget; break; case MouseEvent.MOUSE_RELEASED: // Clear our memory of the original PRESSED event, only if // we're not expecting a CLICKED event after this. If // there is a CLICKED event after this, it will do clean up. if ((--pressCount == 0) && (mouseEventTarget != pressedComponent)) pressedComponent = null; break; } } } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -