2

What is the solution to this problem?

I added a mouse listener to a JPanel, but that panel is full of buttons which cover the entire area of the JPanel.

Example (pseudo) code:

Create JPanel
Set to GridLayout
Add 25 buttons (5x5 grid)
Add MouseListener to JPanel

MouseListener/MouseMotionListener:

onMouseMove { print out X,Y co-ords of mouse }

The co-ords are never printed out until I get right to the edge of the JPanel container, because the buttons are blocking the rest of it.

How can I make the mouse listener work over all of the panel's components without having to add the listener to each component - Or am I supposed to add the listener to each component?

ADDED INFO: I'm trying to add a touch-gesture for a touch-screen system (swiping the panel causes an action to occur). I'm pretty confident about recognising the gesture myself, but I was really looking for a 'better' way than to add a copy of the listener to each component (this would be even worse for me, because the components are changing).

I am going to try to add it to the glassPane instead... (at the moment getRootPane() gives me NullPointerException)

EDIT: I now know that I'm trying to getRootPane() from a JPanel which is not the root container, thats why i'm getting a null. I need to do this on the main JFrame.

EDIT2: Okay so I've done that (added glass pane to main JFrame), at first I had a problem because I didn't do this:

myGlassPane.setVisible(true);

So it seemed like it wasn't working. But once I did that all I had to do was set the opaque flag to false to make it transparent

myGlassPane.setOpaque(false);

So now i'm getting the X,Y co-ords printed out over the buttons and everything, however the buttons aren't working because there's a panel over them.

Ozzy
  • 8,244
  • 7
  • 55
  • 95

2 Answers2

2

Add your listener to both your panel and rhe buttons.

Snicolas
  • 37,840
  • 15
  • 114
  • 173
1

Replace JButton with a custom button. Forward the events you need from the button to the button's parent. Here is an example that will forward the mouse entered event. Adjust forwarding and add exception/error handling as necessary.

class JJButton extends JButton {
    {
        addMouseListener(new MouseAdapter(){
        public void mouseEntered(MouseEvent e) {
            if (JJButton.this.getParent()!=null){
                MouseListener[] ml = JJButton.this.getParent().getMouseListeners();
                for (MouseListener l : ml) {
                    l.mouseEntered(e);
                }
            }
        }
        });
    }
    public JJButton(String string) {
        super(string);
    }    
}
Java42
  • 7,628
  • 1
  • 32
  • 50
  • This would've been what I would have done, had I not finally got my events working through the glass pane, so i'm accepting this as the answer to this question. Thanks. – Ozzy Mar 22 '12 at 01:26
  • This is what I have done now - after finding out the long/hard way that I have no way of making my Java application allow MouseListener events to work with more than 1 layer. Thanks again @ChuckFricano. – Ozzy Mar 22 '12 at 15:20