How To Check Whether EDT (Event Dispatch Thread) Has finished with Dispatching Events In Java
Asked Answered
O

1

6

In my tool, I record events generated from user application. Now user can use my tool to replay his scenario.

While replaying user's recorded scenario, I post recorded events to "EventQueue" one by one using:

eventQueueObj.postEvent(eventObj);

In most of the cases there is no problem in replaying user's recorded scenario.

To explain my problem, I will give short example.

User of my tool want to check whether in his application, "Close" button under "File" menu works or not. His scenario is:

1) Click File Menu.

2) Click Open Menu Item

3) Select File from File Chooser.

4) Click Open on File Chooser.

5) After File is Opened, Click File Menu.

6) Click Close Menu Item.

There is no problem in replaying Step 1 to Step 4. Now at Step 5, I am supposed to wait until file is opened (file being opened is quite large and going to take some time). If I do not wait until file is opened and move forward, "Close" menu item under "File" menu remains disabled. So there is no use of firing Mouse Click Event on "Close" menu item.

My question is "How can I get information from Event Dispatch Thread that it has finished processing of current events?"

After this I can go for clicking on "File" menu and then Step 6.

I don't want to use sleep() to recursively check whether "Close" menu item is enabled or not. Because I want to wait only for required amount of time and not some approximate time.

If I use sleep(), in most of cases I am going to waste some execution time even if user's file open operation is finished.

Overelaborate answered 18/1, 2013 at 11:31 Comment(9)
+1 nice question, but can't think of any simple and robust solution from outside the application being tested (in your tool for ex) :|Tailband
+1 for the question! What if you check EventQueue public AWTEvent peekEvent(). If it's null there is no events to process.Anything
Why do you need to wait? If you post all your events at once on the EventQueue, they will be processed, one at a time, in the order you pushed them.Mexican
My guess is that you can get a lot more control on all this by using your own EventQueueMexican
@GuillaumePolet In my post, I tried to explain a scenario where I need to wait and why.Overelaborate
@YogeshRalebhat Do you mean that the file is being loaded in another Thread than the EDT (if it is, your question is not clear about that)?Mexican
@GuillaumePolet Sorry about question not being so clear. But yes, you are right. It is not always case where each operation is going to be performed on EDT. If some operation is quite large, then user might perform it in another thread (swing components are not accessed in this operation but only required data structures are being created). When this thread is finished, some component is updated in UI. And this is the point in which I am interested.Overelaborate
@YogeshRalebhat Ok but then you have to find some asynchronous way to be notified and continue. Either you add a PropertyChangeListener on one of your view and you wait for a particular PropertyChangeEvent to occur, or you the Observable/Observer pattern on your file loading mechanism. Anyway, peeking the EventQueue is not going to help here.Mexican
I haven't thought of PropertyChangeListener for my case. I think it will help me. I will implement this and lets see if it works. Thanks for brining up this point.Overelaborate
M
3

This should work:

Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent() == null;

A different, asynchronous approach would be to push a special last event and set up a listener for it. Then you won't need to busy-wait by polling the event queue.

Matronage answered 18/1, 2013 at 11:44 Comment(6)
I have already tried asynchronous approach to listen for special last event. This approach solves a problem and I wait only for the required amount of time. But it breaks the current functionality where I was able to replay short interval events. E.g. EventA is event to be fired. EventB is special event for which I going listen. Now after posting EventA to EventQueue and before starting to listen for EventB, EventB is already dispatched from EventQueue.Overelaborate
You should first establish the listener, and only then enqueue the event.Matronage
About 'Toolkit.getDefaultToolkit().getSystemEventQueue().peekEvent() == null;' I will need to use some active loop to check whether events are being processed in event dispatch thread. I am trying to avoid such active loops if there is any better solution for this.Overelaborate
Yes, the better solution is the asynchrounous approach. I'd always go for that and fall back to busy-waiting only in despair.Matronage
You are right Marko. But I have already established listener from the begining of the replay as I also require it for gathering information about components in user application. But as I have list of recorded events, and firiing them one-by-one in sequence, I don't know at what point I am going to face this special event, which must be known by my listener. I cannot start to listen for special event in advance. I must start listening only after firing event previous to special event.Overelaborate
But the event should be special: easily recognized as such by the handling code. Can't you post an event that cannot be confused for a regular one? You can even define your own event class.Matronage

© 2022 - 2024 — McMap. All rights reserved.