javafx中的future.get()阻止了UI更新
我有一个函数,它应该从任务API的结果返回一个列表javafx中的future.get()阻止了UI更新,javafx,concurrency,task,Javafx,Concurrency,Task,我有一个函数,它应该从任务API的结果返回一个列表 @Override public List performQuery(boolean isPaginationQuery, boolean isSortingQuery { try { TaskImpl taskImpl = new TaskImpl(isPaginationQuery, isSortingQuery); q
@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!");
}
}
私有类taskinpl扩展任务{
私有布尔值isPaginationQuery,isSortingQuery;
public TaskImpl(布尔值isPaginationQuery、布尔值isSortingQuery){
this.isPaginationQuery=isPaginationQuery;
this.isSortingQuery=isSortingQuery;
}
@凌驾
受保护的列表调用()引发异常{
Platform.runLater(()->{
loaderContainer.setVisible(true);
loaderContainer.toFront();
});
HSession HSession=新HSession();
TaskInfoDao TaskInfoDao=newtaskinfodaoimpl(hSession.getSession(),currentConnection.getConnectionId());
如果(!isPaginationQuery&&!isSortingQuery){
setTotal(taskInfoDao.getTaskInfoWithFiltersCount(paginator.getFilterMap(),false));
}
Stream resultStream=taskInfoDao.getTaskInfoWithFilters(paginator.getFilterMap(),false,
paginator.getStartIndex()*paginator.getPageSize(),
paginator.getPageSize()*paginator.getPageGap());
列表数据=createData(resultStream);
hSession.close();
返回数据;
}
@凌驾
受保护的无效已成功(){
super.successed();
试一试{
//如果任务已完成,请设置分页
//而且它不是分页查询
如果(!isPaginationQuery){
((TaskInfoViewController)uiController).设置分页(
FXCollections.observearraylist(get());
}
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
}
@凌驾
受保护的作废已取消(){
super.cancelled();
更新消息(“已取消!”);
}
@凌驾
受保护的void失败(){
super.failed();
updateMessage(“失败!”);
}
}
performQuery函数调用线程并等待其结果。正在使用Platform.runLater从TaskImpl类内部显示加载程序。
但加载程序在任务完成之前不会出现,即,在call()函数执行完成后,加载程序才会出现。
当我删除taskImpl.get()时,加载程序工作正常。
感谢您的帮助
注意:在任何情况下,我都需要内部类之外的任务API的结果(在TaskImpl之外)首先,您似乎不太熟悉异步编程。让
performQuery()
返回列表
表明您希望同步运行此操作-在获得结果之前无法返回结果。这就是为什么要冻结UI
关于异步编程,需要了解的重要一点是,您将在另一个线程中开始执行某些操作(即任务),然后立即返回。当任务返回结果时,可以切换回UI(JavaFX应用程序)线程进行更新。您可以将其视为事件驱动的方法
因此,对于您的情况,您应该直接更新在taskinpl
类中重写的succeed()
方法中的列表(在performQuery()
中返回的列表)
如果您应该更新的列表不在taskinpl
的范围内,那么您可以使用java.util.function
包中的函数接口为您进行更新。这意味着您将在正确的范围内创建功能接口对象,并在对象构造期间传入taskinpl
,并在successed()
中调用该接口
更新
如果我假设这是调用performQuery()
:
公共类MyController{
@FXML
TableView TableView;
公共无效初始化(){
列表结果=queryController.performQuery(true,true);
tableView.getItems().addAll(结果);
}
}
然后,我可能会这样做:
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());
}
}
公共类MyController{
@FXML
TableView TableView;
公共无效初始化(){
List result=queryController.performQuery(true,true,List->tableView.getItems.addAll(List));
}
}
公共类查询控制器{
@凌驾
public void性能查询(布尔值isPaginationQuery、布尔值isSortingQuery、java.util.function.Consumer onQuerySucceeded){
试一试{
taskinpl taskinpl=newtaskinpl(isPaginationQuery,
isSortingQuery,onQuerySucceed);
queryExecutor.submit(taskImpl);
}捕获(例外e){
e、 printStackTrace();
}
返回null;
}
}
私有类taskinpl扩展了任务{
private final java.util.function.Consumer onquerysucceed;
public TaskImpl(布尔值isPaginationQuery、布尔值isSortingQuery、java.util.function.Consumer onQuerySucceeded){
this.isPaginationQuery=isPaginationQuery;
this.isSortingQuery=isSortingQuery;
this.onquerysucceed=onquerysucceed;
}
@凌驾
受保护的无效已成功(){
super.successed();
//不知道原始代码在做什么。
试一试{
//如果任务已完成,请设置分页
//而且它不是分页查询
如果(!isPaginationQuery){
((TaskInfoViewController)uiController).设置分页(
FXCollections.observearraylist(get());
}
}捕获(中断异常|执行异常e){
e、 printStackTrace();
}
//这个我
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());
}
}