Java Swing - UI Block - java

I have a GUI and on click event, I am calling database queries to generate multiple charts. I cannot see any chart until all the charts are get completed means there is some problem with GUI components which moves to the next chart before the first chart get complered and show it's contents. What could be the possible reason and how to avoid such problem ?

There is no problem with the components. There is a problem with your design. You're doing the long-running queries and the updates of the charts in a single method run in the event dispatch thread. By doing so, the EDT is completely blocked and can't repaint anything until all the queries have been run and all the charts have been generated.
Use a background thread to execute the queries, and generate a chart, in the EDT, each time one query is finished. The SwingWorker class helps doing that. Read its API doc, and the tutorial about concurrency in Swing.

Related

Enabling/Disabling and updating text in swing components using two different threads other EDT

I am newbie to the swing applications and need some help concurrency in swing.
I would like to know about that there is any bugs will be introduced to the swing application when the two operations such as enabling/disabling of the swing components and updating its content happens in two different threads.
I am trying to do this to improve the performance of the application. For example if enabling/disabling operations on a single JPanel takes 5secs for completion and update text on labels/textfields on the same panel takes 5 secs for completion . If we go with single threaded approach it will take 10secs to complete the whole task.
At the same time if we use two threads; one for enabling/disabling the component and another for updating its content, we can complete the same task in 5secs.
Could anyone provide information on below:
Is there any issue if we follow this approach ?
or any one operation can be done EDT and other can be scheduled run on EDT?
Thanks in advance.

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

The Necessity of dispatching simple events with the EDT

Before I go on discussing the basic query I would first like to state that I am fully aware of my question being against the standards of the AWT/Swing framework. My query is meant merely as a academic experience and should (hopefully) never be applied to real world applications.
The AWT/Swing framework is built upon a event based model which uses a single thread to dispatch events. All AWT/Swing related events events must be processed on the Event Dispatcher Thread (EDT) and any custom events that the programmer has programmed must be queued through the functions invokeAndWait() and invokeLater(). While this model ensures that the framework never suffers from any sort of thread concurrency issues it gives a big pain to programmers trying to write code around it (search swing issues on stackoverflow... quite a handful).
However... Years ago, before I got more familiar with the AWT/Swing model and the EDT I used to write code that violates many many java standards (code that'll make any reasonable programmer recoil in horror). One of these standards I violated was calling methods that updated the GUI through a thread thats not the EDT. To be precise it was a standard "long" task that resided on a secondary thread which periodically updated a JLabel with the current progress. Reviewing the code now I realized that despite the fact that the code directly violated the standard, it worked 100% of the time. I noticed no flickering, no corruption of text (since it was a JLabel), no random exceptions being thrown and no abnormal GUI behavior. Of course I know from one tiny example, one cannot simply determine the AWT/Swing standards are over-protective or unnecessary. And with this, my query lies:
For simple tasks like updating a JLabel (not even at a constant rate, maybe once or twice a second) is it truly necessary to perform it through the EDT? And what are the possible implications (apart from being despised by the whole java programming community) of this (I want a list of solid implications, not just "it might cause the EDT to mess up")?
Assume a model where only one thread updates the GUI (which is not the EDT) and the updates are infrequent and only update in atomic operations (updating strings, primitive data, etc) is it possible that the program can run free of problems caused by the EDT (I guess this counts as a hack?).
As a challenge, I was wondering if its possible anyone can come up with code that demonstrates a violation of the AWT/Swing model by dispatching events from another thread causing obvious and constant (as in I don't have to wait 2 hours for the GUI to flicker for 1 frame) problems?
And by the way, this might be unrelated but does a new EDT thread spawn for a new JFrame/Window object or do all of them run off the same thread? I can't imagine a resource-heavy multi-window system all running off one thread.
NB: I have never seen nor analyzed the source code of the AWT/Swing framework and all my knowledge is based on internet research and personal experience. If there is any mistake above, please feel free to correct me.
For those programmers still in shock from my example above, I have updated all my projects to comply to the standard (what a pain).
An example of where this fails: Set your JLabel to be right-aligned. Then drawing requires two steps - measuring the text, in order to calculate the position, and then drawing it. If you change the text while it is painting (say, due to an animation loop) the text will seem to jump occasionally.
In answer to your other question - there is only one EDT, for all GUI components.
Example of "constant and obvious" change: Suppose the JLabel has HTML content. In your background thread, after the text is set and a repaint is fired, a PropertyChange is also fired, which causes the UI delegate to reparse the HTML and set it in a client property (working in the background thread, although the UI assumes it is in the EDT because it is receiving an event).
So now you have a race condition: If the UI repaints the label (in the EDT) before it finishes calculating the HTML view in the background thread, it will paint the old HTML and your label will appear to not update.
You could say, "Well then, I just won't use HTML in my label." But the point is that situations like this are pervasive in the Swing libraries - a strong assumption is made everywhere that events are passed only on the EDT, and without reading a huge amount of the Swing source you can't guarantee that you won't run into a problem like this.

multithreading for java graphics

I have a java application that streams raw data and draws real time plots accordingly. this is handled by calling methods from a class i wrote that uses the Graphics object. i implemented algorithms in an overridden paintComponent method to generate all the plots from the most recent data. i have other methods in my class to update variables used in the paintComponent method to draw the graphs.
in my main class, i update my graphs periodically in a timer event handler. in the event handler i call methods from my graphs class that update certain variables, do a few calculations, and then call repaint() (which apparently is the correct way to call the paintComponent method).
my problem is, the algorithms i use in the paintComponent method can take a (relatively) long time to complete depending on the amount and resolution of my plots. (i haven't exactly run into this problem yet, but i'm trying to address it now). of course i wouldn't want all this graphing to hog all the processing time of my application, so i was wondering if it's possible to have "paintComponent" execute in a separate thread.
what would happen if i created a subclass in my main to run in a separate thread and simply called the graph methods i described? would that automatically make all of those methods (including paintComponent) execute in the new thread? or would i have to modify my graph class itself for this to work? ideally i would like to avoid modifying my graphs class because i have already designed it to work within the NetBeans GUI builder as a JPanel, and i'd like to avoid breaking that functionality.
There's a couple options.
One method is to use two BufferedImages, where you draw on one in separate thread, and paint from the other one, and switch as drawing completes (for what I assume is a snapshot every so often.)
A much better solution is to have a model of directly renderable data (as in the data it holds can be drawn without performing any further algorithmic work on it).
This means you will perform your alogirthms on a separate thread, calculate the values that will be used to paint, call SwingUtilities.invokeLater to update the model. The model will then only get updated on the Swing thread, and when you repaint, you have access to exactly the data you need to draw (and no extraneous data).
If this data is still so much that painting takes a long time (ie: if you're drawing charts with tons of data points), you'll send to calculate which parts of your window need repainting and fire repaint() on just that. This piece should be a lat resort however. 99% of your performance will come from moving the algorithms into a separate thread, and giving the painter access to directly renderable data.
If you look at best practices on updating a TableModel with external data, what you have is the work that gets the data occurring in a background thread (typically SwingWorker) and then posted to the actual model via invokeLater() (This is so the data doesn't get modified while your paint() is trying to read it.) and then firing appropriate events from within the model update that tell the table what cells changed. The table then knows what part of its viewport needs repainting and fires the appropriate repaint() method. During this time the background thread can continue retrieving data and adding new updates to the event queue via invokeLater.
you have to redirect paint methods to the SwingWorker or Runnable#Thread (all output to the GUI must be wrapped into invokeLater), example here or here
Well, if you want to improve the responsiveness of the GUI you could do the lengthy work in a SwingWorker, although I don't know that doing so will speed up your application any more.
I have a java application that streams raw data and draws real time
plots accordingly. this is handled by calling methods from a class i
wrote that uses the Graphics object.
To complete other's answer:
you should really consider to use JFreeChart. It's a good library for drawing charts and you can modify dynamically the displayed dataset (and do a lot of more things).

Which is better - mainloop or separate threads?

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.

Categories