I am currently working in a implementing a quoridor game in java , using AI game-playing algorithms. After the "human" clicks to make his move , the gui needs to be updated and the AI start thinking.
I have something like this inside the panel:
public void mouseClicked(MouseEvent e)
{
gameBoard.executeMove( movePawn );
repaint();
gameboard.callAi();
}
After I call the funtcion callAi() , I get into a loop that is consuming too much time to finish. The gui on the other hand freezes , it doesnt update , even thought the repaint method is called before the AI "start thinking". I tried to put a delay before I call the AI , but it was not working. I wrote this one:
try
{ TimeUnit.MILLISECONDS.sleep(5);}
catch{}
What can I do to solve this one ? Maybe it has something to do with threads , but I am not too friendly with threads in Java.
I would highly recommend reading up on what the EDT (Event Dispatch Thread) is.
Java Event-Dispatching Thread explanation
One of the answers does a good job explaining it. Quick TLDR: Basically one of the reasons the GUI freezes is because of the AI method you included on the EDT (I can't say for certain about the gameBoard.executeMove(...) method). EDT is meant for updating the GUi, not running methods that take a lot of compute time.
Get the game logic code out of the GUI and into the main thread/new thread (not the EDT). If you absolutely need game logic inside the EDT then make a new Thread in the EDT, have it do its game calculations, and finally use Swing.Utilties.invokeLater(...) method to update the GUI.
Maybe it has something to do with threads , but I am not too friendly with threads in Java.
Definitely want to get familiar with threads when you are making a game, specially the EDT.
You should use a SwingWorker to do the AI work on this. All the updating and processing happens on a single thread within Swing so if you block that then you will freeze the UI.
https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html
Related
At the moment I have a simple Stopwatch code that uses System.currentTimeMillis. My program however freezes when I try to get it to update the JTextField that holds the number of seconds that has passed, it freezes. I've searched around and if I've understood it right I can't have the same "thread" run the infinite loop and the GUI. I am a fairly unexperienced programmer and wondering if threads is something I should even try to grasp/learn/implement.
You should use a different Thread for your business code than the AWT/Swing thread that is updating the UI. If you block the AWT/Swing Thread, the UI will be blocked as well.
Use a new Thread for your countdown and update the UI from the AWT thread, which can be done by SwingUtilities.invokeLater, see https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html#invokeLater%28java.lang.Runnable%29
Threads may look scary at first, but it's not as scary as you think. it is also a good place to start when learning extends and implements. Take a look here for some simple examples to get you started: https://docs.oracle.com/javase/tutorial/essential/concurrency/runthread.html
this is a beginner question:
I am working on a small chat program that use TCP to deliver messages, and I have a simple GUI to display it, I have finished the program, but the EDT has confused me a lot...
does EDT behave like it "extends Thread"? I imagine it is a single thread since I will need worker thread to process the heavy logic, but apparently I can not do Thread.sleep/yield (I have a while loop that constantly reading message from the outputstream and append to the jTextArea, running in main Thread, I tried to terminate the while loop by set a false flag and then yield to main Thread, did not work.)
I am not so sure about how listener works, if I have to write it...I will probably start a thread for each listener, as soon as I hear something I will process it...but this is definitely wrong because it will make EDT a multithread ( a lot of ears ) but singlethread during the process ( only 1 brain )
This must be me lacking knowledge!! because in my head I just can not figure out how to fire an event... you pressed a button and java suddenly knows? I must missed something.
My first time post a question, hope it is clear
The Event Dispatching Thread is a Thread like any other Thread in Java.
It is responsible for dispatching all events and repaint requests (and few other things, like running synchronized Runnable). Any action you take that blocks the EDT will stop it from processing these events, making it look like your application has hung ... because basically it has.
All interactions with any UI component MUST be executed within the context of the EDT. That means you should never try and create or update any UI component from any Thread other then the EDT.
If you need to do any actions that are blocking or time consuming, you should use another thread. SwingWorker is an excellent place to start.
Adding listeners to component will not create more threads. The EDT will post event notifications back to the listeners (this is an incredibly shortened explanation, but the concept is sound), this is one of the reasons why you should never block the EDT.
How events are raised depends on the component. Mouse and keyboard events for example, will be posted to the Event Queue by a native portion of code dependent on the OS/implementation (as I understand it, coming from the ToolKit, but I could be wrong).
actionPerformed events raised by JButtons may be executed directly against the listener (not dispatched via the Event Queue), but within the EDT. This are raised by any number of events, but typically caused by mouse clicks and special key events. The JButton is notified of these because it registers itself with the Event Queue.
While getting an understanding of the workings is a good goal, you need to ask yourself, does it matter (in the short term)? Do you know how electricity gets from the light switch to the light? Or do you only care that it does?
Understand the rules required to use it (don't stick sharp objects into the power points) and let the understanding come as you become more confident.
I've recently started learning and exploring the basics of GUI programming in Java.
Having been programming for a while I have only done backend work or work and as a result the closest I've gotten to user interfaces is the command console (embarrassing I know).
I'm using Swing and as far as I can gather that means by extension I am also using AWT.
My question is based on this piece of code:
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new frame.setVisible(true);
}
} );
I have been researching this for a while as I wanted to fully understand this strange piece of code and have come across the term 'Event-Dispatching Thread' multiple times. Correct me if I'm wrong but as I understand it; it has to do with using multiple threads and how Java Swing interprets those threads. I gather as well that the above code is used to make sure all the threads are 'safe' before it creates the window, hence the invokeLater?
I have read that:
"You can only call methods that operate on the frame from the Event-Dispatching Thread"
and that only under certain circumstances can you call methods that operate on the frame from the main method.
Can somebody please clarify to me what exactly the Event-Dispatching Thread is?
How it relates to multiple threads of execution and how those threads are not safe to be called from the main method? Also why do we need this invokeLater?
Can we not just create the window as any other object?
I've hit a bit of a road block in my research as I'm not grasping these relations and ideas.
A side note is that I like to base my knowledge on in-depth understanding as I believe this leads to the best overall outcome and as a result the best programs. If I understand in-depth how something works then you can use the tips and tweaks effectively rather than just parroting them back in to code, so please don't be afraid to give me some extra in-depth explanations and broaden my knowledge.
Thank you.
The event dispatch thread is a special thread that is managed by AWT. Basically, it is a thread that runs in an infinite loop, processing events.
The java.awt.EventQueue.invokeLater and javax.swing.SwingUtilities.invokeLater methods are a way to provide code that will run on the event queue. Writing a UI framework that is safe in a multithreading environment is very difficult so the AWT authors decided that they would only allow operations on GUI objects to occur on a single special thread. All event handlers will execute on this thread and all code that modifies the GUI should also operate on this thread.
Now AWT does not usually check that you are not issuing GUI commands from another thread (The WPF framework for C# does do this), meaning it's possible to write a lot of code and be pretty much agnostic to this and not run into any problems. But this can lead to undefined behavior, so the best thing to do, is to always ensure that GUI code runs on the event dispatch thread. invokeLater provides a mechanism to do this.
A classic example is that you need to run a long running operation like downloading a file. So you launch a thread to perform this action then, when it is completed, you use invokeLater to update the UI. If you didn't use invokeLater and instead you just updated the UI directly, you might have a race condition and undefined behavior could occur.
Wikipedia has more information
Also, if you are curious why the AWT authors don't just make the toolkit multithreaded, here is a good article.
EventDispatchThread (EDT) is special thread reserved only for Swing GUI and *Swing's related events e.g. create/change/update Swing JComponents, more for asked questions here and here
all output to the GUI from BackGround Tasks, Runnable#Thread must be wrapped into invokeLater(), from synchronized Objects into invokeAndWait();
This question already has answers here:
SwingUtilities.invokeLater() why is it needed?
(7 answers)
Closed 7 years ago.
What does SwingUtilities.invokeLater do? Is it just delaying the execution of a block of codes inside its run method? What is the difference between calling an action within the invokeLater function or simply calling it at the end of the thread we want to be executed? Can anyone help me with what really does the invokeLater function do?
As other answers have said, it executes your Runnable on the AWT event-dispatching thread. But why would you want to do that? Because the Swing data structures aren't thread-safe, so to provide programmers with an easily-achievable way of preventing concurrent access to them, the Swing designers laid down the rule that all code that accesses them must run on the same thread. That happens automatically for event-handling and display maintenance code, but if you've initiated a long-running action - on a new thread, of course - how can you signal its progress or completion? You have to modify a Swing control, and you have to do it from the event-dispatching thread. Hence invokeLater.
It will run the piece of code on the AWT thread. Which lets you modify the GUI from other threads.
From Docs:
Causes doRun.run() to be executed
asynchronously on the AWT event
dispatching thread. This will happen
after all pending AWT events have been
processed. This method should be used
when an application thread needs to
update the GUI.
As already noted, InvokeLater allows you to safely call methods in swing classes when you are not running on the EventQueue to begin with. However, you can simplify your code and your life by accessing other fields and classes only from the EventQueue. They can work with swing and each other without all the hassles of multi-threading. If you have started another thread, use InvokeLater to get back to the EventQueue as quickly as possible and minimize the number of fields that must be synchronized or otherwise guarded.
If you need to make the most of multiple cores you will have to reduce your use of the EventQueue, and you will have to pay a big price in complexity.
that's would be Comment, but looks like as longer as..., just basic stuff
1/ create own EDT for correct update to the GUI, f.e. if you are executed some code by using plain vanilla Thread, java.util.Timer, Executor .. more here
2/ helps with set Focus to the JComponents iof there are some Listeners because if is there f.e. DocumentListener then you hard to set Focus to the desired JComponents
3/ delay code executions block and move that to the ends of EDT
Note that you eventually get a call to your doRun.run( ) method for every time you call invokeLater(doRun). So if you call it ten times before the event thread gets an opportunity to perform its processing, you are likely to then get ten successive calls to doRun.run( ).
I have a start and stop button. I want to be able to start and stop a task as many times as the user wants to. I was able to get this working properly with a regular thread by doing a wait() when the stop button was pushed and then a notify() when the start button was pushed to start the thread again. This worked great. However... I extended thread. My boss told me to never extend thread and that I should use a SwingWorker. But I noticed that a SwingWorker can only be executed once. Or can it be executed more than once in the same session..?? Can somebody help me in the right direction here?
You very rarely need to extend Thread. What you should do is pass a Runnable to a Thread constructor.
For my tastes SwingWorker adds too much coupling to code, and should be left to demos where it works very well.
You can just create a new instance of your SwingWorker each time you want to run the logic. Personally, I don't see much benefit to SwingWorker for your problem as you described it. Not to say it won't do fine...
You don't need a SwingWorker for what you doing. SwingWorker is used for cases when you have to run something in background thread, update your GUI (like progress) without locking i down.
What you did already is fine.