/** * Fire a mouse event to the registered listeners. * * @param eventType * @param button * @param lParam */ private void fireMouseEvent(int eventType, int button, MSLLHOOKSTRUCT lParam) { Logger.trace("fireMouseEvent(eventType={},button={},lParam={})", eventType, button, lParam); MouseListener[] listeners = listenerList.getListeners(MouseListener.class); if (listeners.length > 0) { MouseEvent evt = createMouseEvent(eventType, button, lParam); for (int i = listeners.length - 1; i >= 0; i--) { switch (eventType) { case MouseEvent.MOUSE_PRESSED: listeners[i].mousePressed(evt); break; case MouseEvent.MOUSE_RELEASED: listeners[i].mouseReleased(evt); break; case MouseEvent.MOUSE_ENTERED: listeners[i].mouseEntered(evt); break; case MouseEvent.MOUSE_EXITED: listeners[i].mouseExited(evt); break; } } } }
/** * Fire a mouse wheel event to the registered listeners. * * @param eventType * @param button * @param lParam */ private void fireMouseWheelEvent(int eventType, MSLLHOOKSTRUCT lParam) { Logger.trace("fireMouseWheelEvent(eventType={},lParam={})", eventType, lParam); MouseWheelListener[] listeners = listenerList.getListeners(MouseWheelListener.class); if (listeners.length > 0) { MouseWheelEvent evt = createMouseWheelEvent(eventType, lParam); for (int i = listeners.length - 1; i >= 0; i--) { switch (eventType) { case MouseEvent.MOUSE_WHEEL: listeners[i].mouseWheelMoved(evt); break; } } } }
@Override public LRESULT callback(int nCode, WPARAM wParam, MSLLHOOKSTRUCT lParam) { Logger.trace("callback(nCode={},wParam={},lParam={})", nCode, wParam, lParam); if (nCode >= 0) { Window window = SwingUtilities.getWindowAncestor(relativeTo); Logger.trace("window={}", window); // Is the window active... if (window != null && window.isActive()) { Logger.trace("window is active"); // Is the component showing... // TODO is this still needed or is isActive good enough? if (relativeTo.isShowing() && relativeTo.isValid()) { Logger.trace("window is visible"); // Did the event occur inside the component bounds... int absX = lParam.pt.x; int absY = lParam.pt.y; // FIXME there is a race here where relativeTo may no longer be visible, should // I lock the component tree - is that OK from non-EDT? Point componentPoint = relativeTo.getLocationOnScreen(); int relX = componentPoint.x; int relY = componentPoint.y; int relW = relX + relativeTo.getWidth(); int relH = relY + relativeTo.getHeight(); if (absX >= relX && absY >= relY && absX < relW && absY < relH) { Logger.trace("event inside component bounds"); if (!this.mouseEntered) { this.mouseEntered = true; fireMouseEvent(MouseEvent.MOUSE_ENTERED, MouseEvent.NOBUTTON, lParam); } // The event did occur inside the component bounds, so translate it... switch (wParam.intValue()) { case WM_MOUSEMOVE: fireMouseMotionEvent(MouseEvent.MOUSE_MOVED, MouseEvent.NOBUTTON, lParam); break; case WM_LBUTTONDOWN: fireMouseEvent(MouseEvent.MOUSE_PRESSED, MouseEvent.BUTTON1, lParam); break; case WM_LBUTTONUP: fireMouseEvent(MouseEvent.MOUSE_RELEASED, MouseEvent.BUTTON1, lParam); break; case WM_RBUTTONDOWN: fireMouseEvent(MouseEvent.MOUSE_PRESSED, MouseEvent.BUTTON2, lParam); break; case WM_RBUTTONUP: fireMouseEvent(MouseEvent.MOUSE_RELEASED, MouseEvent.BUTTON2, lParam); break; case WM_MBUTTONDOWN: fireMouseEvent(MouseEvent.MOUSE_PRESSED, MouseEvent.BUTTON3, lParam); break; case WM_MBUTTONUP: fireMouseEvent(MouseEvent.MOUSE_RELEASED, MouseEvent.BUTTON3, lParam); break; case WM_MOUSEWHEEL: fireMouseWheelEvent(MouseEvent.MOUSE_WHEEL, lParam); break; default: break; } } else { Logger.trace("event outside component bounds"); if (this.mouseEntered) { this.mouseEntered = false; fireMouseEvent(MouseEvent.MOUSE_EXITED, MouseEvent.NOBUTTON, lParam); } } } } } return USER32_INSTANCE.CallNextHookEx(hHook, nCode, wParam, lParam.getPointer()); }
@Override public void mouseMoved(MouseEvent e) { Logger.trace("mouseMoved(e={})", e); }