The line
f1.get();
blocks until your thread is done executing. If you execute this line in your UI thread, the UI will freeze, of course. But what are you doing with the result anyway? Without more concrete code, it is hard to give a proper solution to your problem.
** EDIT **
Your controller should execute and handle tasks in it's own thread, and should be completely separated from the UI (for a proper MVC model). Since there are missing information in your code (args
, etc.), an example could be :
Results
public class WebReaderResult<V> {
private AtomicReference<V> ref = new AtomicReference<V>();
public V getResult() { return ref.get(); }
public void setResult(V value) { ref.set(value); }
}
Task
public abstract class WebTask<V> {
private WebReaderResult<V> res = new WebReaderResult<V>();
public WebReaderResult<V> getWebReaderResult() { return res; }
// handle task here
public abstract void handle();
}
Controller
public interface WebControllerCallback<V> {
public void done(V result);
}
public class WebController {
static private WebController instance;
static public WebController getInstance() {
if (null == instance) instance = new WebController();
return instance;
}
private ExecutorService executor = Executors.newSingleThreadExecutor();
public void handleTask(WebTask<?> t, WebControllerCallback<?> cb) {
executor.submit(new Runnable() {
public void run() {
t.handle();
cb.done(t.getWebReaderResult());
}
});
}
// other methods here
}
UI Code
(in your ActionListener, or any other UI event method)
WebTask<String> task = new WebTask<String>() {
public void handle() {
WebReaderResult<String> result = getWebReaderResult();
// TODO : handle task and set result here result.getResult();
}
};
WebControllerCallback<String> callback = new WebControllerCallback<String>() {
public void done(String result) {
// TODO : update UI here from result value
}
};
WebController.getInstance().handleTask(task, callback);
** EDIT 2 **
As mentioned by other users, since Java 1.6 there is a class called SwingWorker
that you may use to do exactly that, but with a lot less code. Just put something like this wherever required in your UI event (or create a separate class to implement the methods) :
new SwingWorker<String, Object>() {
@Override
protected String doInBackground() throws Exception {
// TODO : process result
return "some result";
}
protected void done() {
// TODO : refresh UI with the value of this.get(); which return a String
}
}.execute();
This last edit is not as clear as the first example, however the SwingWorker
class does offer what you are looking for. Now, all you need is to delegate the processing done in both doInBackground
and done
using your WebReader
class (ie. by calling wr.run();
in the doInBackground
, or something.). In any case, I believe you have plenty to go on and about with this now.