📄 mouseevt.java
字号:
/* * * Copyright (c) 1998 * Transvirtual Technologies Inc. All rights reserved. * * Copyright (c) 2004 * Kaffe.org contributors. See ChangeLog for details. * * See the file "license.terms" for information on usage and redistribution * of this file. * * @author P.C.Mehlitz */package java.awt;import java.awt.event.MouseEvent;import java.util.Stack;class MouseEvt extends MouseEvent{ int button; static int clicks; static MouseEvt cache; static boolean buttonPressed; static boolean mouseDragged; static boolean mouseGrabbed; static long lastPressed; static Point mousePos = new Point(); static int xMouseTgt; static int yMouseTgt; static Component[] cFrom = new Component[10]; static Component[] cTo = new Component[10]; static int clickInterval; final static int BUTTON_MASK = BUTTON1_MASK | BUTTON2_MASK | BUTTON3_MASK; static Stack grabStack = new Stack(); static Point nativePos = new Point(); static Point pressedPos = new Point();static { clickInterval = Defaults.ClickInterval;}MouseEvt ( Component src, int evtId, long time, int modifiers, int x, int y, int clickCount, boolean isPopupTrigger) { super( src, evtId, time, modifiers, x, y, clickCount, isPopupTrigger);}static void clickToFocus ( Component newKeyTgt ) { // The JDK does not automatically set the focus on mouse clicks for lightweights, // (non-lightweights probably will be handled by the native window system), i.e. // if a component explicitly requests the focus in respond to a mouse click, the // focus events will be processed AFTER the mouse event. This is the opposite order // compared to native handling (for toplevels). We try to be compatible with // lightweight behavior // note that the JDK allows components which are not isFocusTraversable() to gain // the focus by means of explicit requestFocus() (not very intuitive) OR by means of // mouseclicks (even on components which are not mouse aware, which sounds silly)/* XXX if ( ((newKeyTgt.flags & Component.IS_NATIVE_LIKE) != 0) && newKeyTgt.isFocusTraversable() ) newKeyTgt.requestFocus(); */}static Component computeMouseTarget ( Container toplevel, int x, int y ) { Container cntr; Component c, tgt; int i, xm = 0, ym = 0; tgt = cntr = toplevel; // This is a workaround for no-native-wm Frames with childs extending the Frame size // (the Frame deco border is no separate Component, just "protected" by the Frame insets) if ( (root != null) && (x < cntr.deco.x) || (y < cntr.deco.y) || (x > (cntr.width - cntr.insets.right)) || (y > (cntr.height - cntr.insets.bottom)) ){ return cntr; } i = 0; while (i < cntr.nChildren) { c = cntr.children[i]; if ( ((c.flags & Component.IS_SHOWING) == Component.IS_SHOWING) && (x >= c.x) && (y >= c.y) && (x <= (c.x+c.width)) && (y <= (c.y+c.height)) ) { int u = x - c.x; int v = y - c.y; if ( c.contains( u, v) ){ // contains() might be reimplemented xm += c.x; ym += c.y; // IS_MOUSE_AWARE is a uggly construct to sum up the nice little chain of discriminants: // !disabled && (mouseListener || motionListener || mouseEventMask || motionEventMask || oldEvents) // We assume here that disabled comps don't emit events // If it's a container, reset loop for new // container and continue. if ( c instanceof Container ){ // reset loop for new container tgt = cntr = (Container) c; x = u; y = v; i = 0; continue; } else { // Else it's a leaf of the component tree, // so it gets the event, whether it cn handle // it, or not. tgt = c; break; } } } i++; } xMouseTgt = xm; yMouseTgt = ym; return tgt;}protected void dispatch () { // We handle this on the assumption that native events follow the X-policy // (all events during press and release are routed to the same toplevel). // Don't mix this with our Java mouse handling: we also need to implement // toplevel internal drags/grabs (for lightweights), *and* we need to // override the native grabs for PopupWindow drag ops (where the popup // client toplevel gets all the native events). This corresponds to some // kind of a generalized "OwnerGrabButtonMask" behavior. Component newTgt; //--- the first phase handles mode setting and retargeting if ( mouseGrabbed || mouseDragged || (buttonPressed && (id == MOUSE_MOVED)) ) { // These modes (grab is a generalized drag) don't change the mouseTgt // Note that the first mouseMove after a press is already handled like a drag // (which is initiated by this), but releases might get a different mouseTgt if ( source != AWTEvent.mouseTgt ) { x -= xMouseTgt; y -= yMouseTgt; source = AWTEvent.mouseTgt; } } else if ( id == MOUSE_CLICKED ){ // that one was synthetic, don't change any event fields } else { // determine new target and do exit/enter processing if ( (source instanceof Container) && (source != root) ) { newTgt = (id == MOUSE_EXITED) ? null : computeMouseTarget( (Container)source, x, y); source = newTgt; x -= xMouseTgt; y -= yMouseTgt; } else { newTgt = (id == MOUSE_EXITED) ? null : (Component) source; } // this handles the enter/exit processing if ( newTgt != AWTEvent.mouseTgt ) { transferMouse( this, AWTEvent.mouseTgt, mousePos.x, mousePos.y, newTgt, x, y); } AWTEvent.mouseTgt = newTgt; } //--- now dispatch all the remaining events if ( AWTEvent.mouseTgt != null ) { switch ( id ) { case MOUSE_MOVED: if ( buttonPressed ){ mouseDragged = true; id = MOUSE_DRAGGED; } AWTEvent.mouseTgt.processMotion( this); break; case MOUSE_PRESSED: if ( (AWTEvent.mouseTgt != AWTEvent.keyTgt) ) // decide upon focus policy clickToFocus( AWTEvent.mouseTgt); buttonPressed = true; modifiers = updateInputModifier( button, true); // save current Position so that we can later-on check against ClickDistance pressedPos.x = x; pressedPos.y = y; if ( when - lastPressed < clickInterval ) clicks++; else clicks = 1; clickCount = clicks; lastPressed = when; AWTEvent.mouseTgt.processMouse( this); // some apps might react on isPopupTrigger() for both pressed + released isPopupTrigger = false; break; case MOUSE_RELEASED: clickCount = clicks; buttonPressed = false; updateInputModifier( button, false); if ( mouseDragged ) { // check if we have to generate a enter event for a sibling sendMouseEnterEvent( nativeSource, nativePos.x, nativePos.y, false); mouseDragged = false; } // some display systems can't position the mouse exactly - we tolerate // every release within the Defaults.ClickDistance radius as a valid click if ( !mouseDragged || ((Math.abs(pressedPos.x - x) <= Defaults.ClickDistance) && (Math.abs(pressedPos.y - y) <= Defaults.ClickDistance)) ) { // we can't do this sync because of possible recursion, but we // need to provide a clicked event as the next event to follow // a MOUSE_RELEASE postMouseClicked( AWTEvent.mouseTgt, when, x, y, modifiers, clickCount, button); } AWTEvent.mouseTgt.processMouse( this); break; case MOUSE_CLICKED: clickCount = clicks; AWTEvent.mouseTgt.processMouse( this); break; } // mousePos (used by transferMouse) always contains the LAST mouse pos // (relative to mouseTgt) in order to enable "clean" (non-continuos // move) exits mousePos.x = x; mousePos.y = y; } else { // mouseTgt == null -> toplevel exit mousePos.x = mousePos.y = 0; } if ( (Defaults.RecycleEvents & AWTEvent.MOUSE_EVENT_MASK) != 0 ) recycle();}static synchronized MouseEvt getEvent ( Component source, int id, long when, int mods, int x, int y, int clickCount, boolean isPopupTrigger ) { if ( cache == null ) { return new MouseEvt( source, id, when, mods, x, y, clickCount, isPopupTrigger); } else { MouseEvt e = cache; cache = (MouseEvt) e.next; e.next = null; e.source = source; e.id = id; e.consumed = false; e.when = when; e.modifiers = mods; e.x = x; e.y = y; e.clickCount = clickCount; e.isPopupTrigger = isPopupTrigger; e.button = 0; if ( mods != 0 ) { if ( (mods & BUTTON1_MASK) != 0 ) e.button = 1; else if ( (mods & BUTTON2_MASK) != 0 ) e.button = 2; else if ( (mods & BUTTON3_MASK) != 0 ) e.button = 3; } return e; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -