Sign in to follow this  

[java] Swing/Input threads

This topic is 2849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

In C++ I'd usually be working with a single main thread that looks like this:
while (running)
{
    while (poll_for_events())
    {
        // handle input events

        // handle GUI events
    }

    update_world();

    render_world();
}
In Java, the equivalent for handling the input and GUI events would be creating the appropriate type of Listener and add()ing it to the appropriate Component, like MouseMotionListener, ActionListener, and so on. The only problem is that there is no equivalent for poll_for_events() - all the events are executed in separate Java threads, and that really screws things up. How do I fix it?

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
The only problem is that there is no equivalent for poll_for_events() - all the events are executed in separate Java threads, and that really screws things up. How do I fix it?

Gui events occur in the AWT-event thread, not individual threads. Assuming you're running a game loop in your main thread, I find the easiest is to put the incomming events into a queue and flush the queue in your main loop. Not rocket science really. :P

Share this post


Link to post
Share on other sites
Quote:
Original post by OrangyTang
Quote:
Original post by nullsquared
The only problem is that there is no equivalent for poll_for_events() - all the events are executed in separate Java threads, and that really screws things up. How do I fix it?

Gui events occur in the AWT-event thread, not individual threads. Assuming you're running a game loop in your main thread, I find the easiest is to put the incomming events into a queue and flush the queue in your main loop. Not rocket science really. :P


What about input events? And it's a little difficult to put the events in a queue considering they're implemented as ActionListeners, etc. For example:

JMenuItem exit = new JMenuItem("Exit");
menu.add(exit);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt)
{
running = false;
}
});

I want that to be executed in the main thread.

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
What about input events?
Input events are also generated on the AWT thread.
Quote:
And it's a little difficult to put the events in a queue considering they're implemented as ActionListeners, etc.
I assume he meant that you should write an ActionListener which pushes events onto the queue.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
Input events are also generated on the AWT thread.

Oh alright. Still, I don't want this thread.

Quote:
I assume he meant that you should write an ActionListener which pushes events onto the queue.

That completely kills the idea of using anonymous classes as delegates.

Is there really no way to circumvent this? No manual pump_messages() I can call and a way to disable the AWT thread? How do people normally handle this issue?

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
Quote:
Original post by swiftcoder
I assume he meant that you should write an ActionListener which pushes events onto the queue.
That completely kills the idea of using anonymous classes as delegates.
Ja, I would stick with implementing a named class for this.
Quote:
Is there really no way to circumvent this? No manual pump_messages() I can call and a way to disable the AWT thread?
Nope, nill and nada.
Quote:
How do people normally handle this issue?
They live with it, or they switch back to C++. AWT very sensibly detaches UI update from the rest of the application, but it requires a bit of a paradigm shift on the part of the programmer.

Share this post


Link to post
Share on other sites
Quote:
Original post by swiftcoder
They live with it, or they switch back to C++.

I can't, I'm writing a replacement for the abomination that is GridWorld, and doing it in C++ (or better, C#) would be cheating.

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
Hm, I suppose another solution would be to execute all of my own code inside the AWT thread... Time to figure out how to do that.

Like this:


Timer mainLoop = new Timer(33, new ActionListener() {
public void actionPerformed(ActionEvent evt) {
updateWorld();
repaint();
}
});
mainLoop.start();





Quote:
Is there really no way to circumvent this? No manual pump_messages() I can call and a way to disable the AWT thread?

There's no point. If you disable the event dispatch thread, you'll end up reinventing everything it already does.

Share this post


Link to post
Share on other sites
Quote:
Original post by Dathgale
Quote:
Original post by nullsquared
Hm, I suppose another solution would be to execute all of my own code inside the AWT thread... Time to figure out how to do that.

Like this:

*** Source Snippet Removed ***


Interesting, thanks for pointing that out!

Since I want to run my game loop as fast as possible, would passing 0 as the 'delay' parameter Just Work?

Share this post


Link to post
Share on other sites
Yay, your Timer idea works great [smile]! Basically now my main thread just sleeps while the game loop is running on the AWT-Thread, and all of my ConcurrentModificationExceptions are gone [grin]

Share this post


Link to post
Share on other sites
Quote:
Original post by nullsquared
Since I want to run my game loop as fast as possible, would passing 0 as the 'delay' parameter Just Work?

If you do that, you'll flood Swing with timer events, which it would have to spend time coalescing. It would take less CPU if you did it like this:

EventQueue.invokeLater(new Runnable() {
public void run() {
updateWorld();
repaint();
EventQueue.invokeLater(this); // Re-invoke after all pending events
}
});


Share this post


Link to post
Share on other sites
Quote:
Original post by Dathgale
Quote:
Original post by nullsquared
Since I want to run my game loop as fast as possible, would passing 0 as the 'delay' parameter Just Work?

If you do that, you'll flood Swing with timer events, which it would have to spend time coalescing. It would take less CPU if you did it like this:
*** Source Snippet Removed ***


Oh, OK I got it. Thanks a bunch once again! (rating++)

Share this post


Link to post
Share on other sites

This topic is 2849 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this