Which is better - mainloop or separate threads? - java

The scenario is this: I have Java swing application with JFrame. There is textarea where you can type things, then you get the search results in another textarea and when you select one of the results, there is a button "Download". And here comes the problem. When you hit "Download" the application should display information about the completness of the downloaded files. I've do this with a class extending Thread called DownloadManager which updates the information on a period of time. However I'm concerned that there may be problems with synchronization. Is there a standard way to update such dynamic info without threads? Is there a mainloop or something like this in Java swing classes. How do you do it?

Have a look at SwingWorker:
http://download.oracle.com/javase/6/docs/api/javax/swing/SwingWorker.html
There may be better ways but that's what I used for my progress bar when downloading things and updating progress bars.

Anything that updates the GUI in Java should be done by the GUI event dispatch thread. To force a method to be run in this thread, you need to use the SwingUtilities.invokeLater. Doing anything else could potentially cause your GUI to hang, not update, or other strangeness!
This is a good tutorial that describes it better than I did:
http://www.javamex.com/tutorials/threads/invokelater.shtml

No there are not so much problems with synchronization. If working with background threads in Swing consider to use a SwingWorker.

Related

Java multithreading and SWING

I'm developing a SWING based Java application with multithreading.
The idea is to create a set of background "tasks/services" to do some tasks repeatedly.
My problem is how to implement multithreading (in the lower level of the application) that can interact with the GUI by displaying SWING components at some conditions.
I know I can use SwingWorker but using that I will turn my application more "gui oriented" wich I don't want to but in the other hand I also don't want to make my multithreading classes depended on GUI classes.
What are the options where?
Thank you in advance.
EDIT
I forgot to mention that this background tasks need to be started in the beginning and cannot be launched by the GUI (like a bootstrap process).
but in the other hand I also don't want to make my multithreading
classes depended on GUI classes.
What about using Observer/ Listener pattern? Your background tasks, launched by SwingWorker, can notify some other components when there is such need. #Xeon comment is pointing you in good direction.
Personal advice: start with some solution and then continuously refactor when code became not so readable.
btw. I hope you remember the old rule: Swing components should be accessed on the Event Dispatch Thread only ;)
You need to learn about concurrency design patterns, such as actors, futures, thread pools ect. Event driven means that you don't have blocking code, eg. rather than me waiting on you and constantly asking if you are finished with your task, you simply tell me once you are ready.
If you go the actor route you can wrap your gui class in a controller which is an actor which will process one message at a time. You need to be carefull with swing that you don't create event loops, as in event A triggers event B which triggers event A again and so on.
That's why an obserever pattern can be nice for displaying data.
But there is no silver bullet for concurrency unfortunately, the actor model is picking up, as well as futures, (take a look at akka), but it is essentially a difficult task so it will always be hard to get right.
Essentially I would say that the easiest approach is to make very strict rules on the sort of concurrency you are willing to accomodate, you need to think about the consequences of adding each bit of parallel functionality, and what effect it has. Then design your code based on that using a well established concurrency model.
What you want to do is the standard way most designers would want to do it, that is, have a background worker class which is independent of the GUI.
Creating a class, MySwingWorker, which extends SwingWorker and which calls your background classes is the standard approach. You may want to create one or more dialog classes to wrap your usage of MySwingWorkers, depending on the complexity of your application.

Displaying information from multiple threads in a single JFrame

I start several(threads) instances of a java class that receives an "input" and based on that generates an "output" on out it out on the standard output(screen). I would like to add an option that would enable me to send this output to a single JFrame (text area). What is the best way of doing this? Up to this point my program was totally GUIless but I would like to make it a bit more GUI friendly and add this option.
The challenge is that at any given point I could have several threads running. Any design or code snippets would be greatly appreciated.
As MadProgrammer points out, a nice, encapsulated way of doing this is SwingWorker.
That said, here is the general theory:
All updates to Swing components must be done on the Swing event dispatch thread (there are some exceptions, but not relevant here). This is achieved by SwingUtilities.invokeLater() (and occasionally invokeAndWait() ).
The Swing runtime will then queue up the changes you want to make and call them one at a time. This makes the entire problem of updating your text area pretty trivial: just create a Runnable with the text you want to append, pass that to invokeLater(), and have your Runnable grab the document model of the text area and append your desired text to it.
SwingWorker can encapsulate some of the complexities of background thread management, but I encourage you to do it the 'hard way' a time or two (and your use-case is actually easier to do the 'hard way'). That way you can appreciate what SwingWorker does for you when you do need it.
You need not to convert your existing threads to SwingWorkers. Just let them from time to time send messages to JFrame in a way like this:
EventQueue.invokeLater(new Runnable(){
// update GUI
});
To avoid boilerplate code, it is good to wrap programming interface to the screen with a java.lang.reflect.Proxy. An example of such wrapping is at SwingProxyActorTest.java.

Swing Worker Usage in mixed threads

I have a GUI which consists of a toolbar with each button invoking different classes. The class I invoke consist of UI components which are displayed in the Internal frame of the main GUI. The Invoked class works as a separate thread and has to perform the following functions.
Trigger a command to the client, so that the client starts sending
the contents of a file.
Receive the file contents here,filter it and add it to a JTable.
Progress bar has to be displayed during the file contents transfer.
Display the UI after adding it to the table.
I am new to Swing worker, so can some one help me to get how it works with my situation and the advantages of using Swing Worker and Invoke later function. I followed the examples in the oracle site and few other sites but I am not able to see how this works for my classes.
SwingWorker has...
Progress change functionality built in, via the PropertyChange support
Has helper methods that allow you to synchronise updates to the UI via the publish and process methods, making the process significantly easier...
A self contained workflow concept which makes it (generally) easier to use than rolling your own. There are exceptions to the rule, but your outline doesn't fit those exceptions (IMHO) - this is both and advantage and disadvantage...
For example...
java swingworker thread to update main Gui
JProgressBar won't update
Populating jTable using database data (relates to updating a JTable from a SQL source, but shows how a SwingWorker might be used to update a JTable)
One of the (possible) drawbacks to SwingWorker is it will only allow (I believe) 10 workers to be executed simultanously

Showing a state of another thread in GUI

I have a GUI and the GUI is starting another thread (Java). This thread is starting a class which is crawling many websites. Now I want to show in the GUI how many websites are crawled and how many are left.
I wonder what's the best solution for that.
First idea was to start a timer in the GUI and periodically ask the crawler how many is left. But I guess this is quite dirty...
Then one could pass the GUI to the crawler and it is calling a GUI method every time the count of ready websites changes. But I don't think that's much better?
What is the best way to do something like that?
It depends.
Ask the crawler how much work it is done isn't a bad idea. The benefit is you can actually control when an update occurs and can balance out the load.
The downside is that the information may go stale very quickly and you may never get accurate results, as by the time you've read the values, the crawler may have already changed them.
You could have the crawler provide a call back interface, which the GUI registers to and when the crawler updates it's states, calls back to the GUI.
The problem here is the UI may become swamped with results, causing to lag as it tries to keep up. Equally, while the crawler is firing these notifications, it isn't doing it's work...
(Assuming Swing)
In either case, you need to make sure that any ideas you make to the UI are made from within the Event Dispatching Thread. This means if you use the callback method, the updates coming back will come from the crawlers thread context. You will need to resync these with the EDT.
In this case you could simply use a SwingWorker which provides mechanisms for syncing updates back to the EDT for you.
Check out Concurrency in Swing for more details
register a callback function to your thread. when your data is dirty, invoke this callback function to notify GUI thread to update. don't forget to use synchronization.

Is update from EDT in swing an absolute rule or are there exceptions?

In Swing, the GUI is supposed to be updated by the EDT only, since the GUI components are not thread safe.
My question is, if I have a single thread, other than the EDT, that is dedicated to update a specific component, and this component is not accessed by any other thread in my program, only this dedicated thread, is it ok? In my case I have a JTable and a thread receives information from the network and updates the table (without using EventQueue.invokeLater). All the other components are updated from the EDT. I have not seen a problem so far, and I was wondering if a bug will surface eventually.
UPDATE
My purpose was to update the table in real-time. The data come constantly from the network and for this I dedicated 1 thread just for the table, to update it constanlty as they come. If I use the SwingUtilities.invokeLater, this means that the table will be updated when the EDT is available. Is not swing supposed to be used for real-time update requirements?
Instead of trying to reason about whether it will or won't work, I would just stick to the well-known 'rule' which is that you should only interact with GUI components using the event dispatching thread. When you receive data from the network, just update the table using SwingUtilities.invokeLater (or invokeAndWait).
You might not see problems straight away, but it's quite possible you might do in the future.
There are a few methods documented as thread-safe. I believe a few less in JDK7, because it turns out some of them are unimplementable as thread-safe. For the most part Swing is thread-hostile - it has to be used from the AWT EDT thread. This is largely because it uses EventQueue.invokeLater internally at "random". Also there is hidden shared state (you can change the PL&F without having to tell each component for instance). Some classes you may be able to treat as thread-agnostic, but they are not documented as such.
So the answer is, always use the EDT for Swing. As with most threading bugs, you might seem to get away with it and then suddenly fail in production. The bug is likely to be difficult to diagnose and reproduce (particularly if it only happens in production on certain systems). Fixing a code base that is severely broken may not be fun. Keep it clean from the start.
You must update GUI components on the EDT. Period. (There are a couple of legacy exceptions to this rule - but they were all silently putting things over to the EDT anyway). The EDT operates as a message pump (as most windowing systems do) - you have to live within that constraint if you want to update GUI components.
If you want your table to update quickly, keep the EDT clean - don't put any huge load onto it.
If you are working with updating live tables, I strongly recommend that you take a look at GlazedLists - they have a very, very good SwingThreadProxyList implementation that takes care of efficiently posting updates to the EDT. You have to agree to drink the GlazedLists koolaid to go this route, but it is mighty tasty koolaid (I love GL).
Is not Swing supposed to be used for real-time update requirements?
No. You may be able to update your data model at a sufficient rate, but the GUI is typically subordinate. You may be able to take advantage of any network latency in your environment. Alternatively, you may need to consider something like Oracle's Sun Java Real-Time System.
You can improve the "liveness" of the EDT by keeping updates brief and using the minimal, correct synchronization. Several alternatives are discussed here.
It is an absolute rule, unless you want race conditions. The event dispatch thread is fast enough for our CCTV app's display not to need hacks.

Categories