I have a SwingWorker
which calls some code that does not check for thread interruption. After the call to worker.cancel(true)
, the worker.get()
method will throw CancellationException
immediately (as it is supposed to). However, since the background task's code never checks for its thread to be interrupted, it happily continues executing.
Is there a standard way to wait for the background task to actually finish? I'm looking to show a "Cancelling..." message or something of the sort and block until the task has terminated. (I'm sure I could always accomplish this with a flag in the worker class if necessary, just looking for any other solutions.)
The closest thing to a standard, or ready-made way of doing this is the
progress
property and/or the publish/process method pair provided bySwingWorker
. You can set this to a "I'm finished" value at the end of the method to indicate the background work is done. The thread waiting on the swing worker can put up a "Canceling..." message and periodically check the progress to see if it has reached completion. If the waiting thread is the swing EDT, then you will need to use a Timer to periodically check the progress property and clear the cancel message when done.Here's some example code that runs a stubborn background thread, which is canceled, and then waits until the progress reaches 100.
An alternative approach is to use the
publish\process
method pairs to push a special value indicating that the background thread has finished into the EDT. Yourprocess
override method in SwingWorker then picks up this special value and hides the "Canceling..." message. The advantage with this is that no polling or timers are needed. The example code shows that althoughdone
is called as soon as the task is canceled, the publish/process method pairs still work even when the task is cancelled.I played around with this a bit and here's what I came up with. I'm using a
CountDownLatch
and basically exposing itsawait()
method as a method on mySwingWorker
object. Still looking for any better solutions.Inspired by the solution by Paul Blessing I improved it a little to become a class, you can subclass to get the desired funcitonality: