MouseListener for JPanel missing mouseClicked events
Asked Answered
E

5

12

I have a JPanel that I have created a MouseListener for and I am seeing some behavior that I can't explain.

Usually when I click the mouse within the JPanel, I see the following events fire:

mousePressed
mouseReleased
mouseClicked

On some occasions, I don't see the mouseClicked event fire, I only see:

mousePressed
mouseReleased

I don't think I'm doing anything out of the ordinary when I click these times. Could anyone explain why I might not be seeing the mouseClicked event?

I'm not sure if it's relevant, but I do have an animation running in the panel using a javax.swing.Timer.

Any help is appreciated.

EDIT: adding test code that replicates problem. I'm not sure, but I wonder if my mouse has anything to do with it. I have one of those super sensitive gaming mice (from my old COD4 days).

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JPanel;


public class Test {

    public static void main(String[] args) {
        final Test test = new Test();
        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                test.createAndShowGUI();
            }
        });
    }

    protected void createAndShowGUI() {
        JFrame frame = new JFrame();
        frame.setPreferredSize(new Dimension(1024, 768));
        frame.setTitle("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setBackground(Color.WHITE);

        panel.addMouseListener(new MouseListener() {
            @Override
            public void mouseReleased(MouseEvent e) {
                System.out.println(":MOUSE_RELEASED_EVENT:");
            }
            @Override
            public void mousePressed(MouseEvent e) {
                System.out.println("----------------------------------\n:MOUSE_PRESSED_EVENT:");
            }
            @Override
            public void mouseExited(MouseEvent e) {
                System.out.println(":MOUSE_EXITED_EVENT:");
            }
            @Override
            public void mouseEntered(MouseEvent e) {
                System.out.println(":MOUSE_ENTER_EVENT:");
            }
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println(":MOUSE_CLICK_EVENT:");
            }
        });

        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }

}
Enthuse answered 1/8, 2010 at 14:18 Comment(3)
Can you post some code ?Gametophore
Just added a class that replicates the problem. I thought it might be that my mouse was too sensitive and I was getting mouseMoved events between the mousePressed and mouseReleased events, but I added a listener for mouseMoved and I could replicate the problem without seeing a mouseMove in the middle.Enthuse
Thanks for this question, along with all the answers. I had exactly the same problem! (Probably my sensitive mouse as well).Ravenna
E
19

Per http://download.oracle.com/javase/tutorial/uiswing/events/mouselistener.html:

"You will see a mouse-released event. If you did not move the mouse, a mouse-clicked event will follow."

I just had this problem. If you move the mouse AT ALL, a clicked event won't happen. I truly have no idea what good mouseClicked is given this knowledge. I fixed it by using mouseReleased and checking if the mouse was within the object:

public void mouseReleased(MouseEvent e) {
    if(objectWithListener.contains(e.getPoint())){
        doClickAction();
    }
}
Eustoliaeutectic answered 10/6, 2011 at 16:0 Comment(0)
E
3

I think I found the problem here. I was getting intermediate mouseDragged events between the mousePress and mouseRelease. mouseMoved didn't seem to cause the problem, but mouseDragged did.

I'm not sure of the right solution now, but at least now I can explain what is happening.

Cheers

-Bill

Enthuse answered 3/8, 2010 at 16:56 Comment(0)
D
1

My solution looks like this: pointToHex maps mouse coordinates to the identity of an object in my View. If the coordinates map to the same object on click and release I register a clicked event.

addMouseListener(new MouseAdapter() {

            HexAddress clickedHex = null;

            public void mousePressed(MouseEvent e) {
                clickedHex = calc.pointToHex(e.getX(), e.getY());
            }

            public void mouseReleased(MouseEvent e) {
                if (clickedHex != null && clickedHex.equals(calc.pointToHex(e.getX(), e.getY()))) {
                    mapEventListener.hexClicked(clickedHex);
                    HexMapView.this.repaint();
                }
                clickedHex = null;
            }
        });
Dudleyduds answered 9/8, 2020 at 6:22 Comment(0)
P
0

A couple of suggestions for those having this problem.

First: it could be your mouse is getting old. I was getting weird behaviour and it turned out to be the mouse occasionally throwing coordinates that were way off and it would then jump back to its original position. This will give mouse drag events. Try a different mouse...

Second: I had a problem where I needed a jPanel(A), which I was drawing on, set as BorderLayout.CENTER layout inside another jPanel(B) which was, itself, inside a jScrollPane.

When jPanel(B) was resized, the drawing panel(A) would scale to the correct size because of the BorderLayout layout manager but (A) would ignore any clicks outside its original dimensions if (A) was now bigger than its original size.

When jPanel(B) was resized, the layout manager was not setting (A)'s dimensions to the new size when it scaled (A) to fit in the CENTER of jPanel(B). The mouse click event would only fire for clicks inside the original dimensions of jPanel(A). I had to manually set the size of jPanel(A) to its new scaled dimensions in order to get mouse clicks for all areas of jPanel(A).

Putrescine answered 25/2, 2013 at 23:7 Comment(0)
V
0

In the cases when all I want is the clicked-event, then I use a simple ActionListener instead of the MouseListner. The actionPerformed event does, for buttons and alike atleast, get fired just like we want a click-event to be, i.e. as long as the mouse is at the same control at release time as it was at pressed time, an actionPerformed event will be fired.

Votary answered 17/9, 2013 at 11:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.