Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java MouseEvent, check if pressed down

I have a class that implements MouseListener (JPanel). When I click on the panel something happens. What I want is some kind of while-loop that loops as long as left mousebutton is pressed down.

@Override
public void mousePressed(MouseEvent e) {
    while(e.isPressedDownD) {      // <--
        //DO SOMETHING
    }
}

This obviously doesn't work, but I hope you understand what I'm trying to achieve. The whole class for those that are interested:

package control;

import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import model.GridModel;
import view.GUIView;

public class MapListener implements MouseListener{
    private GridModel model;
    private GUIView view;
    private int posX;
    private int posY;

    public MapListener(GridModel model, GUIView view) {
        this.model = model;
        this.view = view;
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        posX = e.getX();
        posY = e.getY();
        model.setMouseAtX(posX);
        model.setMouseAtY(posY);
        view.paintTile();
        System.out.println("X: " + posX + " Y: " + posY);
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent arg0) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        while(e.getModifiers() == MouseEvent.MOUSE_PRESSED) { //Obviously doesn't work
            //DO SOMETHING
        }
    }

    @Override
    public void mouseReleased(MouseEvent arg0) {
    }
}
like image 765
Sane Avatar asked Jul 26 '11 10:07

Sane


2 Answers

As pointed out by other answers, the place to do your work is not in the mouse event listener methods.

Also there is no explicit "mouse pressed" notion in MouseEvent, so you must track that yourself. I have provided an example of how to do this. Also note the MouseEvent.BUTTON1 references, as this is just to track the state of the left mouse button.

This is where you must start to learn about concurrency. For that reason, I've added in a synchronized method as you need to be aware that funny things happen when multiple threads access properties at the same time, and synchronized is a mechanism for keeping this sane. Consider it further reading beyond the scope of this example.

Untested, but this should work:

volatile private boolean mouseDown = false;

public void mousePressed(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        mouseDown = true;
        initThread();
    }
}

public void mouseReleased(MouseEvent e) {
    if (e.getButton() == MouseEvent.BUTTON1) {
        mouseDown = false;
    }
}

volatile private boolean isRunning = false;
private synchronized boolean checkAndMark() {
    if (isRunning) return false;
    isRunning = true;
    return true;
}
private void initThread() {
    if (checkAndMark()) {
        new Thread() {
            public void run() {
                do {
                    //do something
                } while (mouseDown);
                isRunning = false;
            }
        }.start();
    }
}
like image 160
Charles Goodwin Avatar answered Oct 03 '22 14:10

Charles Goodwin


Why do so many of these answers wrongly assert that there is no explicit "mouse pressed" notion in MouseEvent?

Although the other commenters are correct that the OP should not be doing all that stuff in an event handler, there are other situations in which querying the button state in a mouse listener is useful. In those cases, you actually CAN determine the button down state. For example:

@Override
public void mouseExited(MouseEvent event) // Or any other mouse event handler...
{
    int buttonsDownMask = MouseEvent.BUTTON1_DOWN_MASK 
            | MouseEvent.BUTTON2_DOWN_MASK 
            | MouseEvent.BUTTON3_DOWN_MASK; // Or whichever buttons you care about...
    if ( (event.getModifiersEx() & buttonsDownMask) != 0 )
        System.out.println("Hey! Some button is pressed!");
}

Notice in particular the use of the MouseEvent.getModifiersEx() method, along with MouseEvent.BUTTON1_DOWN_MASK and friends.

like image 37
Christopher Bruns Avatar answered Oct 03 '22 16:10

Christopher Bruns