Calling code after all mouse event listeners are executed

I created a panel on which a set of objects is drawn. Each of the objects is added as a mouse event listener to the panel. As I know, after an event occurs, listeners are notified, and the code can be (or is there?) Executed in several threads. Is it possible to include custom code that will be executed after all listeners have finished executing their code?

0
source share
3 answers

Regarding Noel's comment:

The problem with this method being triggered is that a particular listener implementation returns a notification earlier and does the work out of band in a separate thread. In this case, the end of the notification call does not actually indicate the end of the listener's execution. If this is an actual issue (i.e. you are aware and interested in other custom, thoughtful listeners who do such things, you may need to clarify and revise the issue.

Using SwingUtilities.invokeLater() , you are sure that the code is executed after notifying all listeners. But one of these listeners can do this work in a separate thread.

If you need to execute your code after all the listeners have not only been notified, but also finished, you can do something like this:

<sub> pseudo-code: sub>

 Listener implements MouseListener +mouseClicked( event: MouseEvent ) SwingUtilities.invokeLater( // returns immediately someTask() ) -someTask() // perform some long task. 

If you have your listeners like

  addListener( new Listener() ) addListener( new Listener() ) addListener( new Listener() ) addListener( new ExecuteAtTheEnd() ) 

If all (or some) of your listeners do their work in another thread. Your ExecuteAtTheEnd can execute its code at the end of the notification, but not at the end of the listeners code execution.

So what are you doing?

You need to synchronize the use of some lock flag and execute your code until this flag is used.

It can be a counter that increases when the listener executes and decreases the value if it is not:

  Listener implements MouseListener +mouseClicked( event: MouseEvent ) lockFlagCount++ SwingUtilities.invokeLater( someTask() ) -someTask() // perform some long task. lockFlag-- 

And then you just continue until this flag is false:

  ExecuteAtTheEndListener implements MouseListener + mouseClicked( event: MouseEvent ) SwingUtilities.invokeLater( executeAtTheEnd() ) - executeAtTheEnd() while( logFlagCount > 0 ) wait() if( logFlagCount == 0 ) // continue with the task. 

Of course, this is much more complicated since I put it in pseudo-code, but it should work if you are in such circumstances.

+1
source

Running in the same thread (event dispatcher thread).

To do what you want, you just need to add an extra listener and make this listener call the executeLater SwingUtilities class method.

What is, waits until the EDT thread completes the notifications, and then calls your code.

To test this, add this listener and see what it does:

  class MouseListener extends MouseAdapter { public void mouseClicked(MouseEvent e) { // System.out.println("If uncommented this would be invoked with the rest of the listners"); SwingUtilities.invokeLater( new Runnable() { public void run() { System.out.println("Invoked after all the listeners were notified"); } } } } 

Of course, this is a mouse listener that you have. The concept is the same for all other listeners.

+3
source

I believe that you need to use the SwingUtilities.invokeLater() method, which will call the Runnable instance in the Thread Dispatch Thread after all other GUI events have been processed.

0
source

All Articles