views:

463

answers:

5

Hi all.

I would like to know if there exists in Java an event that is continuously fired when a mouse button is being held down (pressed), even if the mouse is not moved. I could not find it in typical MouseListeners:

  • MouseDragged is fired only if the user move the mouse while holding the button down
  • MousePressed is fired only once when the button has been pressed

And that's about it. Any idea how to make such an event?

Cheers

jy

+5  A: 

If you need to do something whilst the mouse button is down, just start it when you detect a mousePressed event and then continuously do that until you detect a mouseReleased event. Then you don't need to have your event continuously firing. e.g.

public void mousePressed(MouseEvent e) {
    someCondition = true;
    while(someCondition) {
        //do something
    }
}

public void mouseReleased(MouseEvent e) {
    someCondition = false;
}

EDIT: As others have said, the code would need to be separated from the event thread otherwise the call to mouseReleased would get blocked preventing the loop from ending.

James
You'll probably want to decouple from the event handler thread.
Alex Feinman
+7  A: 

There is an obvious reason why this event is not available in MouseListener: it's going to spam you with events such that everything is slowed down to a halt. Do you want to receive this event every second, every ms, or even more often? If you need that you'll have to do it yourself.

For stearing this process you of course need mousePressed and mouseReleased to determine whether a button is currently held down. Then you need to run some kind of loop that generates the corresponding events you'd like to have.

You might also want to work via polling, i.e. extend your MouseListener class such that it can tell you whether a button is still held down, and whereever you need those events you can actively poll for the button. It depends on how you want to use these events, which approach is more suitable.

Frank
+1  A: 

There is no such event

You can create your own by starting a timer in the mousedown method and ending the same timer in the mousereleased

You will also need a few fail saves to make sure the timer stops when you do mousedown the movemove onto another component or even onto other frame or non java gui parts

Peter
A: 

I think you'll find the answer is no, there is no such event. Not just for Java, but for any GUI framework. It would serve no purpose other than to tie up the event queue.

You would need to create your own by trapping the mouse down event then having a timer fire events at regular intervals until the mouse up event.

Dave Kirby
+3  A: 

James Goodwin's code will not work. mousePressed and mouseReleased are both fired from the GUI thread, so blocking in mousePressed will prevent mouseReleased from ever being fired, meaning the loop will continue forever.

If you already have a seperate thread for processing then use mousePressed to indicate to that thread that the event should start, and mouseReleased to stop.

If you don't have a separate thread and don't want the hassle, a Timer is probably the easiest way. javadoc on Timer.

Specifically, you should create a TimerTask that does whatever it is you want to do multiple times and queue it using Timer.schedule:

Timer timer = new Timer();
TimerTask task = new MyTimerTask();

private class MyTimerTask extends TimerTask {
    public void run() {
        // your code here
    }
}

public void mousePressed(MouseEvent e) {
    timer.scheduleAtFixedRate(task, 0, 1000); // Time is in milliseconds
    // The second parameter is delay before the first run
    // The third is how often to run it
}

public void mouseReleased(MouseEvent e) {
    task.cancel();
    // Will not stop execution of task.run() if it is midway
    // But will guarantee that after this call it runs no more than one more time
}

I'm pretty sure this is the simplest way, as it doesn't involve faffing around with inter-thread communication.

Oh, and as Peter said, you will have to add code to account for the user mousing down on your app and mousing up somewhere else.

ZoFreX
Thanks for pointing out that the code wouldn't work as expected, I had only given the code as a rough example and hadn't tested that it would actually work.
James