Линия
f1.get();
блокирует, пока не завершится выполнение вашего потока. Если вы выполните эту строку в потоке пользовательского интерфейса, пользовательский интерфейс, конечно же, остановится. Но что ты делаешь с результатом в любом случае? Без более конкретного кода трудно дать правильное решение вашей проблемы.
** РЕДАКТИРОВАТЬ **
Ваш контроллер должен выполнять и обрабатывать задачи в своем собственном потоке и должен быть полностью отделен от пользовательского интерфейса (для правильной модели MVC). Поскольку в вашем коде отсутствует информация (args
и т. Д.), Примером может быть:
Результаты
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); }
}
Задача
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();
}
Контроллер
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
}
Код интерфейса пользователя
(в вашем ActionListener или любом другом методе события пользовательского интерфейса)
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);
** РЕДАКТИРОВАТЬ 2 **
Как уже упоминали другие пользователи, начиная с Java 1.6 существует класс под названием SwingWorker
, который вы можете использовать именно для этого, но с гораздо меньшим количеством кода. Просто поместите что-то подобное в любое место вашего события пользовательского интерфейса (или создайте отдельный класс для реализации методов):
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();
Последнее редактирование не так понятно, как в первом примере, однако класс SwingWorker
предлагает то, что вы ищете. Теперь все, что вам нужно, это делегировать обработку, выполняемую как в doInBackground
, так и done
, используя ваш класс WebReader
(то есть, вызывая wr.run();
в doInBackground
или что-то в этом роде). В любом случае, я полагаю, вам есть над чем поработать.