I'm programming a robot that uses an interface with buttons and a text box and stuff, and I know that if you are using
Thread.sleep();
then it will pretty much break your interface. I know that
Thread.sleep();
pretty much just pauses your current thread and resumes it after an allotted amount of time. I need to have a slight pause in my program without breaking my interface, such as an interface equivalent of
Thread.sleep(1000);
I've looked for hours and I can't find anything to create a slight pause in one part of your program while maintaining an interface. Also I don't know about multithreading so please explain stuff in as much detail as possible. Thanks in advance for helping me!
Everything in a Java Swing user interface runs on a single, special thread (the Swing thread or "event dispatching thread"). If you block this thread with a Thread.sleep() then your user interface stops responding.
To be able to sleep (i.e. deliberately delay some processing) without blocking the user interface, your program may need to run on multiple threads. I suggest you take a look at the Java tutorial on this topic. Multithreading is a fairly advanced topic that can't really be summarised in a short answer.
It's not clear what you are trying to achieve with your sleep - if you just want some action to be triggered at a future time, then the Timer class may do what you need without needing extra threads.
There are also some helper classes in the Java libraries for running tasks on other threads in a GUI application.
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I heard many times that Java Swing threading model is wrong. I don't fully understand why, I know that the problem is related to the fact that you can draw on a Drawable from another thread other than the main UI thread. I know that there are utility functionalities like SwingUtilities.invokeAndWait and SwingUtilities.invokeLater that let you do your painting in a Runnable, that in turn is run by the Event Dispatcher thread. I guess that this way you ensure that painting is done synchronously and this doesn't leave the buffer in an incosistent state.
My question is: how do "good" UI toolkits behave? What solutions are adopted?
Brian Goetz's Java Concurrency in Practice,
9.1 Why are GUIs single-threaded?:
...In the old days, GUI applications were single-threaded and GUI events
were processed from a “main event loop”. Modern GUI frameworks use a
model that is only slightly different: they create a dedicated event
dispatch thread (EDT) for handling GUI events. Single-threaded GUI
frameworks are not unique to Java; Qt, NextStep, MacOS Cocoa, X
Windows, and many others are also single-threaded. This is not for
lack of trying; there have been many attempts to write multithreaded
GUI frameworks, but because of persistent problems with race
conditions and deadlock, they all eventually arrived at the
single-threaded event queue model in which a dedicated thread fetches
events off a queue and dispatches them to application-defined event
handlers...
For SWT: http://book.javanb.com/swt-the-standard-widget-toolkit/ch05lev1sec7.html
SWT implements a single-threaded user interface model that is typically called apartment threading. In this model, only the user interface thread can invoke user interface operations. This rule is strictly enforced. If you try to access an SWT object from outside the user interface thread, you will get an SWTException("Invalid thread access").
So SWT is single-threaded too. But it takes the extra step to forbid any changes to the UI outside of the UI thread. Consider the alternative in Swing where modifying the UI from somewhere else is allowed but will produce sooner or later unexpected results that will confuse the newbie programmer who will then learn that Swing is single-threaded the "hard" way.
Also, if your design is not clear, you may end up with situations where you think you are in the correct thread but in actuality you are not. You can also be unable to tell reliably what threads will access a specific piece of code, but then you probably have a serious design issue in you own code anyway.
Other than that, I can't imagine other reasons why Swing's threading model would be considered "wrong".
The way current display technologies are implemented, painting pixels on a screen is always serial. You need to generate about 30 images a second, and paint them one by one.
So there is no need for this painting to be multi-threaded, because you would still have to do some synchronization in the background. And this is actually what Swing is doing - it uses a special thread called Event Dispatch Thread to schedule all changes to occur in time before the next image.
So technically, Swing is thread-safe, IF you use the EDT to submit changes. And that's what invokeLater() and invokeAndWait() methods are for. They submit changes to the EDT.
If you don't use EDT and submit some long-running change, such as computing some value after a button press, you can see the application become unresponsive, not repainting itself. Because the EDT is busy doing the calculation for you, and have no time to schedule repaints and other events.
Swing has a thread that is responsible for basically letting the user interact with the graphical portion of your application. If you only perform quick tasks in response to user initiated events, your application will always be responsive.
You might have an issue if you perform a long running task, from an user initiated event, without using a separated thread to run that task - the problem is that, while the task is running, the application will freeze. No repaints will occur, the user will not be able to interact with it all, it will look like the application just locked itself out.
If you are running a task in a separated thread (for example, you are downloading a page and you want to notify the user that the download has completed), then you can't update Swing directly from that task, instead you must use one of the helper methods you mentioned in your question.
It is a more labor-intensive process to create these tasks so that your application is always responsive - but if you are running something that takes a long time (downloading a file is a good example), the application will continue to be responsive even while the task is performed, and you can even let the user cancel the task, just as long as the task itself allows it. You can use a modal dialog to prevent the user from doing anything else while the task is performed (if you want to do so), or have a progress dialog that displays a spinning wheel or something like that. But I guess the important thing is not let the user think that the application just "froze" for no reason.
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
I have found that in order to keep Java GUIs (using Swing) responsive the only way is to use the SwingWorker class, as opposed to java.lang.Thread. Is SwingWorker truly the only way when it comes multithreaded GUI based desktop apps? Are there any good alternatives? Rarely can I configure the Thread class to do what I want to do, but SwingWorker usually works, if sometimes in a cumbersome way.
SwingWorker is nothing but a thin convenience API around Thread. Therefore it is definitely possible to use Thread without SwingWorker. The main point is that Swing is not thread-safe and any actions you perform on Swing objects must happen on the Event Dispatch Thread. This is the fundamental obstacle, and SwingWorker tries to help you overcome it a bit more conveniently.
The alternative is a continuation using EventQueue.invokeLater(), but SwingWorker has important advantages:
It synchronizes granular access to data shared between itself and the EDT.
It provides property change support for progress indication.
It implements the Future interface.
See also Worker Threads and SwingWorker for details.
Multithreading in GUI application is difficult to implement since there can be so many actions that trigger actions. A good explanation of why is this a "failed dream" can be found here
Multithreaded toolkits: A failed dream.. For solutions to your problem, read this article on concurrency in swing: Concurrency in Swing
Depending on your duration of the action you can go with SwingUtilities.invokeLater() or make a SwingWorker for tasks that take a long time to complete and run in background.
You must use this classes or else you may be in situations where a thread will block your entire application and may seem unresponsive to the user.
Another option, most suitable for repetitive tasks, is javax.swing.Timer (it can be used for one-shot tasks as well).
Case of study:
I have a program with some model classes and some GUI classes in Swing where I use several threads in both of them which run an infinite loop with different sleep intervals for each runnable. two of model threads run a very critical job in which if the delay rises from 40ms to 60ms will not work correctly anymore so they are extremely critical.
But I have hundreds of components in GUI that must be updated in less than a second or more frequently. These components can't be updated with observer design pattern because they don't reflect only the changes in the model. they should calculate something such as remaining time.
Problem
I think that it will not be efficient to use hundreds of Runnables
invoked with SwingUtilities.invokeLater(runnable) to update all
GUI components. Because the context switch will have an enormous
side-effects. So I'm going to avoid it. Should I really avoid
creating all those runnables or invokeLater() or swing timer doesn't run them as a thread and has an optimizing method even with all the Thread.sleep(500) among them ?
For solving the above problem I decided to create an Interface SwingUpdatable with an update method. And create a SingleTonSwingUpdater which is run evry 500ms and run all the update methods of the classes registered with it. The observer design pattern made me to think about this idea. But I'm afraid that it will be an anti-pattern. And I'm not sure if it will reduce the flexiblity of the program.
What if I use swing Timer. It surely can't understand that if the TimerTasks all should be run in 500ms time interval so there shouldn't be a new thread for them and it's enough to do a loop on the runnables and execute them one after another.
Does Java have a built-in solution for this problem or is there a design pattern I can use or I should rely on my solution that at the first looks so dirty?
SwingUtilities.invokeLater(runnable) adds runnable in a queue and then GUI thread executes them one at a time, so context switching is minimal. Avoid using Thread.sleep() in jobs running on GUI thread, use Swing timer instead.
The proposed "solution" adds latency to the data visualization, and has no benefits. Be careful to add solutions to the problems you do not fully understand. Human intuition works badly inside computer.
Swing's timer manages queue of timed jobs and passes them to the GUI thread when the delay expires. This is quite efficient approach.
What problem are you talking about? Hundreds events per second is not so much, standard approaches should work. If they do not, probably they are misused.
Well, if you have a long list of Runnables waiting to be executed, the time spent on EDT will grow and your timing may go off. But you should do at least a cursory test to see whether this will happen. Otherwise you'll be trying to solve a problem you don't have.
You could maybe try to coalesce events together to avoid doing unnecessary work. As a final remark, if your application is so time sensitive, you'll need to pay attention to the garbage collection as well (although this shouldn't be your first worry).
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();