Is it feasible to implement some util method to suspend test (current thread) execution until application becomes idle?
Idle means:
1. there were no GUI events added to event queue for some period of time
2. there were no worker threads running any tasks for the same period of time.
Could you please provide implementation/code snippets to track previous conditions of idleness?

- 20,010
- 25
- 97
- 140
2 Answers
You can replace the EventQueue
with your own implementation, as shown here. The variation below adds an idle()
method that relies on an arbitrary THRESHOLD
of 1000 ms.
import java.awt.AWTEvent;
import java.awt.EventQueue;
import java.awt.Toolkit;
import java.lang.reflect.InvocationTargetException;
import javax.swing.JFrame;
import javax.swing.JTree;
/**
* @see https://stackoverflow.com/questions/7976967
* @see https://stackoverflow.com/questions/3158254
*/
public class EventQueueTest {
public static void main(String[] args) throws
InterruptedException, InvocationTargetException {
EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
final MyEventQueue q = new MyEventQueue();
eventQueue.push(q);
EventQueue.invokeAndWait(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame("Test");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new JTree());
f.pack();
f.setVisible(true);
}
});
// Test idle() on initial thread
for (int i = 0; i < 10; i++) {
Thread.sleep(2 * MyEventQueue.THRESHOLD);
System.out.println("Idle: " + q.idle());
}
}
private static class MyEventQueue extends EventQueue {
private static final int THRESHOLD = 1 * 1000;
private long last;
@Override
public void postEvent(AWTEvent e) {
super.postEvent(e);
last = System.currentTimeMillis();
}
public boolean idle() {
return System.currentTimeMillis() - last > THRESHOLD;
}
}
}
-
I _think_ this is comprehensive; see also this [Q&A](http://stackoverflow.com/questions/7787998/how-to-generate-exceptions-from-repaintmanager) about finding EDT violations. – trashgod Nov 02 '11 at 17:20
-
This solution is not working by for relaying the fact that event processing time is smaller then recheck interval. By comparing the last dispatch time you can't garantee there are no pending events waiting for execution. You can check the queue to be empty (there is API) but this will be not working neither. It is needed 'in progress' flag noution to be checked with checking for empty queue. But this will also not working because there is noution of 'flashing' event queue (putting hadware events to event queue of application). – Mike May 03 '12 at 22:06
-
1I had tried to do this in a similar way: http://stackoverflow.com/questions/8080018/event-dispatching-filter-chain – Mike May 17 '12 at 10:30
You can use Toolkit.getDefaultToolkit().addAWTEventListener(listener, eventMask)
to subscribe to AWT event queue, so you can detect whether events are not added for some period of time.
I think that you need your custom code to monitor working threads, i.e. something in the beginning and end of run()
method.
The problem is to "suspend the test execution". If your test is running in thread theoretically you can invoke the thread's suspend()
method. But it is deprecated and should not be used. To perform clear implementation you should make your custom code that asks status during execution of the thread and calls wait()
once it detects that the test must be suspended. When your code that monitors AWT event queue and working threads decides that test may be resumed it should call appropriate notify()
.
Probably better solution from design point of view is Actors model. There are several java framework that provide this functionality.

- 114,158
- 16
- 130
- 208
-
There is no problem with "suspend test execution". I'm to use that util method from tests itself thus I'm to use LockSupport.park* to suspend tests just like ReentrantLock does. The problem is to "track ideless". Thanks for idea about GUI events. – Mike Nov 02 '11 at 08:13