我有一个函数,它应该从Task API的结果中返回一个列表。
@Override
public List performQuery(boolean isPaginationQuery, boolean isSortingQuery {
try {
TaskImpl taskImpl = new TaskImpl(isPaginationQuery,
isSortingQuery);
queryExecutor.submit(taskImpl).get();
return taskImpl.get();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
执行更新的内部类
private class TaskImpl extends Task<List> {
private boolean isPaginationQuery, isSortingQuery;
public TaskImpl(boolean isPaginationQuery, boolean isSortingQuery) {
this.isPaginationQuery = isPaginationQuery;
this.isSortingQuery = isSortingQuery;
}
@Override
protected List call() throws Exception {
Platform.runLater(() -> {
loaderContainer.setVisible(true);
loaderContainer.toFront();
});
HSession hSession = new HSession();
TaskInfoDao taskInfoDao = new TaskInfoDaoImpl(hSession.getSession(), currentConnection.getConnectionId());
if (!isPaginationQuery && !isSortingQuery) {
paginator.setTotal(taskInfoDao.getTaskInfoWithFiltersCount(paginator.getFilterMap(), false));
}
Stream<TaskInfo> resultStream = taskInfoDao.getTaskInfoWithFilters(paginator.getFilterMap(), false,
paginator.getStartIndex() * paginator.getPageSize(),
paginator.getPageSize() * paginator.getPageGap());
List<TaskInfoTableView> data = createData(resultStream);
hSession.close();
return data;
}
@Override
protected void succeeded() {
super.succeeded();
try {
//set the pagination if the task is complete
//and it is not a pagination query
if (!isPaginationQuery) {
((TaskInfoViewController) uiController).setPagination(
FXCollections.observableArrayList(get()));
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
@Override
protected void cancelled() {
super.cancelled();
updateMessage("Cancelled!");
}
@Override
protected void failed() {
super.failed();
updateMessage("Failed!");
}
}
performQuery函数调用线程并等待其结果。
使用Platform.runLater从TaskImpl类内部显示加载器
但是,在任务完成之后才会出现加载程序,即在完成call()函数执行后出现加载程序。
当我删除taskImpl.get()时,加载器工作正常
任何帮助表示赞赏。
P.S。 :无论如何,我需要在Inner类之外的Task API的结果(在TaskImpl之外)
答案 0 :(得分:2)
首先,您似乎对异步编程不是很熟悉。让performQuery()
返回List
表示您希望同步运行此 - 在获得结果之前,您无法返回结果。这正是你冻结UI的原因。
了解异步编程的重要一点是,您将启动在另一个线程中执行某些操作(即任务),并立即返回 。当从任务返回结果时,您切换回UI(JavaFX Application)线程以更新它。您可以将此视为事件驱动方法。
因此,对于您的情况,您应该在performQuery()
类中已覆盖的succeeded()
方法中直接更新列表(您在TaskImpl
中返回的列表)。< / p>
如果您要更新的列表不在TaskImpl
的范围内,那么您可以使用java.util.function
包中的功能接口为您执行此操作。这意味着您将在正确的范围内创建该功能接口对象,并在对象构造期间传入TaskImpl
,并在succeeded()
中调用该接口。
如果我认为这就是调用performQuery()
:
public class MyController {
@FXML
TableView<Foo> tableView;
public void initialize() {
List result = queryController.performQuery(true, true);
tableView.getItems().addAll(result);
}
}
然后,我可能会做这样的事情:
public class MyController {
@FXML
TableView<Foo> tableView;
public void initialize() {
List result = queryController.performQuery(true, true, list -> tableView.getItems.addAll(list));
}
}
public class QueryController {
@Override
public void performQuery(boolean isPaginationQuery, boolean isSortingQuery, java.util.function.Consumer<List> onQuerySucceeded) {
try {
TaskImpl taskImpl = new TaskImpl(isPaginationQuery,
isSortingQuery, onQuerySucceeded);
queryExecutor.submit(taskImpl);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
private class TaskImpl extends Task<List> {
private final java.util.function.Consumer<List> onQuerySucceeded;
public TaskImpl(boolean isPaginationQuery, boolean isSortingQuery, java.util.function.Consumer<List> onQuerySucceeded) {
this.isPaginationQuery = isPaginationQuery;
this.isSortingQuery = isSortingQuery;
this.onQuerySucceeded = onQuerySucceeded;
}
@Override
protected void succeeded() {
super.succeeded();
// Not sure what the original codes are doing.
try {
//set the pagination if the task is complete
//and it is not a pagination query
if (!isPaginationQuery) {
((TaskInfoViewController) uiController).setPagination(
FXCollections.observableArrayList(get()));
}
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
// This is what is being added in
onQuerySucceeded.accept(this.getValue());
}
}