Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detecting mouse enter/exit events anywhere on JPanel

Tags:

java

Basically there is a JPanel on which I want to know when the mouse enters the area of the JPanel and exits the area of the JPanel. So I added a mouse listener, but if there are components on the JPanel and the mouse goes over one of them it is detected as an exit on the JPanel, even though the component is on the JPanel. I was wondering whether anyone knows any way to solve this problem without doing something like adding listeners onto all components on the JPanel?

like image 704
Mano Avatar asked Mar 15 '10 05:03

Mano


People also ask

What is a MouseListener interface that occur when the cursor enters or exits a component's onscreen area and when the user presses or releases one of the mouse buttons?

Mouse events occur when the cursor enters or exits a component's onscreen area and when the user presses or releases one of the mouse buttons. Tracking the cursor's motion involves significantly more system overhead than tracking other mouse events.

What methods do you use to register a handler for a mouse pressed released clicked entered exited moved and dragged event?

To register a handler object, you invoke the source object's registration method; for example, button. setOnAction (handler) for registering a handler for a button action event. To implement a handler interface, you implement the method defined in the handler interface.

What is a MouseListener?

MouseListener and MouseMotionListener is an interface in java.awt.event package . Mouse events. are of two types. MouseListener handles the events when the mouse is not in motion.

Which event is invoked when a mouse button is pressed and the mouse is moved on an AWT object?

mouseDragged. Invoked when a mouse button is pressed on a component and then dragged.


Video Answer


2 Answers

There is a very easy solution for this problem that can work :

public class MyJPanel implements MouseListener {

    public void mouseExited(MouseEvent e) {
        java.awt.Point p = new java.awt.Point(e.getLocationOnScreen());
        SwingUtilities.convertPointFromScreen(p, e.getComponent());
        if(e.getComponent().contains(p)) {return;}
        ...//the rest of your code
    }

    ...
}

This way you just ignore the mouseExited event when it occurs on a child element.

like image 123
Darksharcoux Avatar answered Oct 20 '22 17:10

Darksharcoux


Here is one way to do it for a component that may contain other components:

  1. Add a global AWT event listener to get all mouse events. For example:

    Toolkit.getDefaultToolkit().addAWTEventListener( 
       new TargetedMouseHandler( panel ), AWTEvent.MOUSE_EVENT_MASK );
    
  2. Implement the TargetedMouseHandler to ignore events that aren't sourced by the panel or by one of the panel's children (you can use SwingUtilities.isDescendingFrom to test for this).

  3. Keep track of whether or not the mouse is already within the bounds of your panel. When you get a MouseEvent.MOUSE_ENTERED event in your panel or one of its children, set a flag to true.

  4. When you get a MouseEvent.MOUSE_EXITED event, only reset the flag if the point in the MouseEvent is outside the bounds of your target panel. SwingUtilities.convertPoint and Component.getBounds().contains() will come in handy here.

like image 38
Ash Avatar answered Oct 20 '22 17:10

Ash