In my application I have a main frame window GUI
, that launches a task in an executor
service.
The submitted task generates
output and stores in a file on Disk
.
As soon as the o/p is generated GUI (observer) is informed of the o/p generated.
Here the problem is I am keeping a wait loop inside the main frame and as soon as a notification is received, the main panel is repainted on the main frame.
For small tasks this works fine, but as the size of the threaded task increases. The wait loop time increases and the GUI main window turns black till computations are done.
Can you please help me in correcting the design. Also How can a SwingWorker
thread help in this case.
1) Wait loops are the bane of all that is GUI. They are OK in other threads you have spawned, tricky in Executors (as they sometimes have limits on number of Threads, depending on which you use), and are completely out of the question on the EDT. That is the reason for your "blackscreen"
2) Instead of using a custom (I assume it's custom) signal protocol and a wait loop, you could use one of the utility classes in Swing. For example,
SwingUtilities
has a couple of nice methods -invokeLater
andinvokeAndWait
that take aRunnable
and execute it on the EDT as soon as they can. Using this instead of the signal you have will allow you to not block the EDT and make your GUI responsive.3) If you really want to use a
SwingWorker
you may want to look through the documentation for it. It is essentially a way to do background tasks and report progress or completion/result to the EDT. Currently it uses anExecutorService
with 2 background threads, so having a lot of long running tasks on them is not a good idea (they will block each other). When creating aSwingWorker
you would specify the method to be ran in the background, the method to be ran on the EDT when intermediate results are available, and the method to be ran on the EDT when you're finished either successfully or in error.4) This does not pertain to the question at hand, but if you ever get into a situation where you need a wait loop in the EDT and cannot avoid it using another design or technique, you can always switch to using a
Timer
. It can be setup to be called every x milliseconds without blocking the EDT and turned off once you are satisfied with some condition.Then you long running task is executing on the Event Dispatch Thread (EDT) which prevents the GUI from repainting itself. You need to execute the long running task in a separate Thread. A SwingWorker is a separate Thread which has an API that also allows you to execute code on the EDT as required, for example when the code finishes executing or when you have intermediate results.
Read the section from the Swing tutorial on Concurrency for more information. You can always search the forums for example of using a SwingWorker.