I am writing an application in java (1.6) using swing. I currently have a JXBusyLabel on a JXLayer over the content area of my program acting as a busy indicator. I want to provide a way to allow others working with me to create a task that pops up the busy label while it's executing. The catch is, the task must be cancel-able. What is the best way to expose the functionality I desire?
Some ideas I've come up with:
- Raw access to setBusy()
This is obviously the easiest for me but requires users know and understand swing threading issues. - public <T> Future<T> execute(Callable<T>)
Wraps the callable in a FutureValue that is run() on a separate thread and returns that FutureValue. The question then becomes, how to keep track of all FutureValue's generated and how to ensure that they can be cancelled. (e.g. cancel(true) always cancels)
I have never used the concurrency package in Java before and it didn't exist back when I 'learned' Java. So I am open to completely new and different ways of implementing this functionality.
Edit:
Clarification of my question. I know about SwingWorker. I've just never used it. What I want to know is this:
Given a Callable (Java version of a closure?) How can I:
- Return the value of call() to the user w/o blocking (I think I need to use a Future for this)
- Tell the JXLayer to lock (starts painter), execute the supplied callable, and then unlock the JXLayer (stops painter)
- Ensure that, no matter what thread calls my busyExec() function, the GUI remains responsive and the background task completes. (NOTE: If I return some sort of Future object and they call get() on the event thread, it can/will block and that is ok)
I guess my main stumbling point is how to implement #2. Should I have busyExec() spin off a new thread that blocks until no background tasks are running? Should I try for some sort of queue. Is there an object that will do this all for me already?