I use SwingUtilities.invokeLater to update the UI. Sometimes tasks are executed almost at as soon as invokeLater is called, but sometimes it takes few seconds for it, that I would like to avoid. Are there any settings that can help me with this?
I know that tasks are executed in a AWT event-dispatching thread, but is there a way to forcefully clear the queue of it (probably not a great idea), or somehow add another AWT thread to work in parallel, or any other solution that may help with executing tasks faster?
Is it even possible to influence this things, or all I can do is just create some daemon threads by myself? I'd like to avoid that.
There are things that have to be done on the event handler thread. Swing isn't thread-safe, and not following that rule makes WEIRD things happen.
As there is only one such thread (and you can't create additional ones), make sure it's used only for things where it's necessary. So, don't do complex computations on that thread. Check your paintComponent() methods, invokeLater() calls etc. for time-consuming parts.
Either optimize their performance or refactor them to some other "worker" thread. You can have as many worker threads as you like, as long as they stay away from calling Swing methods. The fact that you are asking about invokeLater() implies that you're already using at least one thread besides the event handler.
A decent profiler tool will be helpful in that process.
Have you tried SwingUtilities.invokeAndWait()? It sounds like you don't want to have the program do other things threaded with the Swing operations, you want them done right now.
Of course this won't actually caused them to be done in any fewer CPU cycles, and if there are things already queued up for the dispatch thread, this doesn't get rid of them or anything.
There are also things like loading up images from files that can either be done synchronously or asynchronously -- if you're trying to eliminate pauses, you might make sure those are being done as you want.
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'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.
What is the usual way to implement animations (e.g. a composite with a changing position, in SWT) so that they look equally fast on all machines?
The naive approach would be to use timestamps, to stop the time untill the next animation step.
Is there a more professional way?
I use the javax.swing.Timer on a regular basis, and it works great for consistent animations. All you have to do is implement a class (you can even make it your Frame or Panel) that implements ActionListener.
The timer calls the actionPreformed(...) method at an interval specified in the constructor (or later if you want), and you can perform all of your redrawing from the Timer intervals. Usually that involves updating the state of whatever object you need and calling repaint() on the Panel involved.
Make sure you call the Timer's start() method. That has caused me numerous headaches!
The only approach is using timestamps; the naïve and professional approaches differ in how they are used.
The naïve approach uses a thread and Thread.sleep(). The professional approach uses timers to run code at certain intervals and let the timer decide how to handle delays and jitter.
You can learn more about timers, look at the classes Timer and TimerTask. java.util.Timer.scheduleAtFixedRate(TimerTask, Date, long) should be a good start. Just be aware that the code is executed in a new thread, so you need to use the usual tools to inject events into the UI thread's queue.
I've often heard criticism of the lack of thread safety in the Swing libraries. Yet, I am not sure as to what I would be doing in my own code with could cause issues:
In what situations does the fact Swing is not thread safe come into play ?
What should I actively avoid doing ?
Never do long running tasks in response to a button, event, etc as these are on the event thread. If you block the event thread, the ENTIRE GUI will be completely unresponsive resulting in REALLY pissed off users. This is why Swing seems slow and crusty.
Use Threads, Executors, and SwingWorker to run tasks NOT ON THE EDT ( event dispatch thread).
Do not update or create widgets outside of the EDT. Just about the only call you can do outside of the EDT is Component.repaint(). Use SwingUtilitis.invokeLater to ensure certain code executes on the EDT.
Use EDT Debug Techniques and a smart look and feel (like Substance, which checks for EDT violation)
If you follow these rules, Swing can make some very attractive and RESPONSIVE GUIs
An example of some REALLY awesome Swing UI work: Palantir Technologies. Note: I DO NOT work for them, just an example of awesome swing. Shame no public demo... Their blog is good too, sparse, but good
This is one of those questions that makes me glad I purchased Robinson & Vorobiev's book on Swing.
Anything that accesses the state of a java.awt.Component should be run inside the EDT, with three exceptions: anything specifically documented as thread-safe, such as repaint(), revalidate(), and invalidate(); any Component in a UI that has not yet been realized; and any Component in an Applet before that Applet's start() has been called.
Methods specially made thread-safe are so uncommon that it's often sufficient to simply remember the ones that are; you can also usually get away with assuming there are no such methods (it's perfectly safe to wrap a repaint call in a SwingWorker, for example).
Realized means that the Component is either a top-level container (like JFrame) on which any of setVisible(true), show(), or pack() has been called, or it has been added to a realized Component. This means it's perfectly fine to build your UI in the main() method, as many tutorial examples do, since they don't call setVisible(true) on the top-level container until every Component has been added to it, fonts and borders configured, etc.
For similar reasons, it's perfectly safe to build your applet UI in its init() method, and then call start() after it's all built.
Wrapping subsequent Component changes in Runnables to send to invokeLater() becomes easy to get right after doing it only a few times. The one thing I find annoying is reading the state of a Component (say, someTextField.getText()) from another thread. Technically, this has to be wrapped in invokeLater(), too; in practice, it can make the code ugly fast, and I often don't bother, or I'm careful to grab that information at initial event handling time (typically the right time to do it in most cases anyway).
It's not just that Swing is not thread-safe (not much is), but it's thread-hostile. If you start doing Swing stuff on a single thread (other than the EDT), then when in cases where Swing switches to the EDT (not documented) there may well be thread-safety issues. Even Swing text which aims to be thread-safe, isn't usefully thread-safe (for instance, to append to a document you first need to find the length, which might change before the insert).
So, do all Swing manipulations on the EDT. Note the EDT is not the thread the main is called on, so start your (simple) Swing applications like this boilerplate:
class MyApp {
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() { public void run() {
runEDT();
}});
}
private static void runEDT() {
assert java.awt.EventQueue.isDispatchThread();
...
An alternative to using intelligent skins like substance is to create the following utility method:
public final static void checkOnEventDispatchThread() {
if (!SwingUtilities.isEventDispatchThread()) {
throw new RuntimeException("This method can only be run on the EDT");
}
}
Call it in every method you write that is required to be on the event dispatch thread. An advantage of this would be to disable and enable system wide checks very quickly, eg possibly removing this in production.
Note intelligent skins can of course provide additional coverage as well as just this.
Actively avoid doing any Swing work at all except on the event dispatching thread. Swing was written to be easy to extend and Sun decided a single-threaded model was better for this.
I have had no issues whilst following my advice above. There are some circumstances where you can 'swing' from other threads but I've never found the need.
If you're using Java 6 then SwingWorker is definately the easiest way to deal with this.
Basically you want to make sure that anything that changes a UI is performed on the EventDispatchThread.
This can be found by using the SwingUtilities.isEventDispatchThread() method to tell you if you are in it (generally not a good idea - you should know what thread is active).
If you aren't on the EDT then you use SwingUtilities.invokeLater() and SwingUtilities.invokeAndWait() to invoke a Runnable on the EDT.
If you update UI's not on the EDT you get some incredibly strange behaviour. Personally I don't consider this a flaw of Swing, you get some nice efficiency by not having to synchronize all of the threads to provide a UI update - you just need to remember that caveat.
The phrase 'thread-unsafe' sounds like there is something inherently bad (you know... 'safe' - good; 'unsafe' - bad). The reality is that thread safety comes at a cost - threadsafe objects are often way more complex to implement (and Swing is complex enough even as it is.)
Also, thread-safety is achieved either using locking (slow) or compare-and-swap (complex) strategies. Given that the GUI interfaces with humans, which tend to be unpredictable and difficult to synchronize, many toolkits have decided to channel all events through a single event pump. This is true for Windows, Swing, SWT, GTK and probably others. Actually I don't know a single GUI toolkit which is truly thread-safe (meaning that you can manipulate its objects' internal state from any thread).
What is usually done instead is that the GUIs provide a way to cope with the thread-unsafety. As others noted, Swing has always provided the somewhat simplistic SwingUtilities.invokeLater(). Java 6 includes the excellent SwingWorker (available for previous versions from Swinglabs.org). There are also third party libraries like Foxtrot for managing threads in Swing context.
The notoriety of Swing is because the designers have taken light handed approach of assuming that the developer will do the right thing and not stall the EDT or modify components from outside the EDT. They have stated their threading policy loud and clear and it's up to the developers to follow it.
It's trivial to make each swing API to post a job to the EDT for each property-set, invalidate, etc., which would make it threadsafe, but at the cost of massive slowdowns. You can even do it yourself using AOP. For comparison, SWT throws exceptions when a component is accessed from a wrong thread.
Here's a pattern for makng swing thread-freindly.
Sublass Action (MyAction) and make it's doAction threaded.
Make the constructor take a String NAME.
Give it an abstract actionImpl() method.
Let it look like.. (pseudocode warning!)
doAction(){
new Thread(){
public void run(){
//kick off thread to do actionImpl().
actionImpl();
MyAction.this.interrupt();
}.start(); // use a worker pool if you care about garbage.
try {
sleep(300);
Go to a busy cursor
sleep(600);
Show a busy dialog(Name) // name comes in handy here
} catch( interrupted exception){
show normal cursor
}
You can record the time taken for the task, and next time, your dialog can show a decent estimate.
If you want to be really nice, do the sleeping in another worker thread too.
Note that not even the model interfaces are thread safe. The size and the content are queried with separate get methods and so there is no way of synchronizing those.
Updating the state of the model from another thread allows for it to at least paint a situation where size is still bigger (table row is still in place), but the content is no longer there.
Updating state of the model always in EDT avoids these.
invokeLater() and invokeAndWait() really MUST be used when you are doing any interaction with GUI components from any thread that is NOT the EDT.
It may work during development, but like most concurrent bugs, you'll start to see weird exceptions come up that seem completely unrelated, and occur non-deterministly - usually spotted AFTER you've shipped by real users. Not good.
Also, you've got no confidence that your app will continue to work on future CPUs with more and more cores - which are more prone to encountering weird threading issues due to them being truely concurrent rather than just simulated by the OS.
Yes, it gets ugly wrapping every method call back into the EDT in a Runnable instance, but that's Java for you. Until we get closures, you just have to live with it.
For more details about threading, Taming Java Threads by Allen Holub is an older book but a great read.
Holub, really promotes responsive UI and details examples and how to alleviate problems.
http://www.amazon.com/Taming-Java-Threads-Allen-Holub/dp/1893115100
http://www.holub.com/software/taming.java.threads.html
Love the "If i was king" section in the end there.