Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MouseListener for JPanel missing mouseClicked events

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);
    }

}
like image 406
BillMan Avatar asked Aug 01 '10 14:08

BillMan


3 Answers

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();
    }
}
like image 199
Andrew Avatar answered Nov 17 '22 01:11

Andrew


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

like image 31
BillMan Avatar answered Nov 17 '22 01:11

BillMan


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;
            }
        });
like image 1
tgdavies Avatar answered Nov 16 '22 23:11

tgdavies