Java 在GUI线程中的繁重工作期间显示ProgressIndicator必须完成
在JavaFXUI线程中执行一些繁重的操作时,是否有可能显示(旋转,而不是卡住)进度指示器 背景故事: 我必须将一个相当大的tableView加载到标题窗格中(这需要几秒钟)。使整个过程滞后的命令是TitledPane.setContent(myTableView)。 所以我想在这段时间内至少显示一些加载动画或指示器 因此,现在我正在做以下工作,在进行昂贵的调用之前,为ui线程提供足够的空间来显示我的加载动画:Java 在GUI线程中的繁重工作期间显示ProgressIndicator必须完成,java,javafx,ui-thread,progress-indicator,Java,Javafx,Ui Thread,Progress Indicator,在JavaFXUI线程中执行一些繁重的操作时,是否有可能显示(旋转,而不是卡住)进度指示器 背景故事: 我必须将一个相当大的tableView加载到标题窗格中(这需要几秒钟)。使整个过程滞后的命令是TitledPane.setContent(myTableView)。 所以我想在这段时间内至少显示一些加载动画或指示器 因此,现在我正在做以下工作,在进行昂贵的调用之前,为ui线程提供足够的空间来显示我的加载动画: showMyLoadingAnimation(); PauseTransition
showMyLoadingAnimation();
PauseTransition pause = new PauseTransition(Duration.seconds(1));
pause.setOnFinished(event -> {
setContent(myTableView);
});
pause.play();
dismissMyLoadingAnimation();
这可以让进度指示器显示出来,但是一旦ui线程开始处理setContent,它就会被卡住
我见过一些人使用swing来显示动画的布局或对话框,只是为了让它在不同的线程中运行,而不是陷入困境,但还找不到令人信服的解决方案
编辑:
好的,我找到了问题的根源。
因此,我将tables prefHeightProperty绑定到其显示的列表的大小,如下所示:
几周前就做了,工作了,忘了
那要花很多时间。因此,尽管设置绑定时对调用进行计时并不表明这需要花费很多时间,但当表越来越大时,ui线程似乎有一个很大的问题
多亏了詹姆斯,对于大多数遇到这种问题的人来说,他的答案是正确的
有人能在那边评论一下这个问题吗
(因为这是第一个问题,我没有足够的代表发表评论)在后台线程中加载数据。启动任务时显示加载动画(或等),并在任务完成时将其删除
其基本思想如下:
TableView<MyDataType> table = new TableView<>();
// set up columns...
Task<List<MyDataType>> loadDataTask = new Task<List<MyDataType>>() {
@Override
protected List<MyDataType> call() throws Exception {
List<MyDataType> data = ... ;
// load data and populate list ...
return data ;
}
};
loadDataTask.setOnSucceeded(e -> table.getItems().setAll(loadDataTask.getValue()));
loadDataTask.setOnFailed(e -> { /* handle errors... */ });
ProgressIndicator progressIndicator = new ProgressIndicator();
table.setPlaceHolder(progressIndicator);
Thread loadDataThread = new Thread(loadDataTask);
loadDataThread.start();
TableView table=newtableview();
//设置列。。。
Task loadDataTask=新任务(){
@凌驾
受保护的列表调用()引发异常{
列表数据=;
//加载数据并填充列表。。。
返回数据;
}
};
loadDataTask.setOnSucceeded(e->table.getItems().setAll(loadDataTask.getValue());
loadDataTask.setOnFailed(e->{/*处理错误…*/});
ProgressIndicator ProgressIndicator=新的ProgressIndicator();
表.setPlaceHolder(progressIndicator);
线程loadDataThread=新线程(loadDataTask);
loadDataThread.start();
在后台线程中运行,在中加载数据。启动任务时显示加载动画(或等),并在任务完成时将其删除
其基本思想如下:
TableView<MyDataType> table = new TableView<>();
// set up columns...
Task<List<MyDataType>> loadDataTask = new Task<List<MyDataType>>() {
@Override
protected List<MyDataType> call() throws Exception {
List<MyDataType> data = ... ;
// load data and populate list ...
return data ;
}
};
loadDataTask.setOnSucceeded(e -> table.getItems().setAll(loadDataTask.getValue()));
loadDataTask.setOnFailed(e -> { /* handle errors... */ });
ProgressIndicator progressIndicator = new ProgressIndicator();
table.setPlaceHolder(progressIndicator);
Thread loadDataThread = new Thread(loadDataTask);
loadDataThread.start();
TableView table=newtableview();
//设置列。。。
Task loadDataTask=新任务(){
@凌驾
受保护的列表调用()引发异常{
列表数据=;
//加载数据并填充列表。。。
返回数据;
}
};
loadDataTask.setOnSucceeded(e->table.getItems().setAll(loadDataTask.getValue());
loadDataTask.setOnFailed(e->{/*处理错误…*/});
ProgressIndicator ProgressIndicator=新的ProgressIndicator();
表.setPlaceHolder(progressIndicator);
线程loadDataThread=新线程(loadDataTask);
loadDataThread.start();
标题窗格.setContent(myTableView)代码>实际上不可能花费任何可观的时间。代码中发生的其他事情正在占用时间;可能正在加载数据。您应该将耗时的工作(不是实际的UI工作)移动到后台线程。titledPane.setContent(myTableView)代码>实际上不可能花费任何可观的时间。代码中发生的其他事情正在占用时间;可能正在加载数据。您应该将耗时的工作(不是实际的UI工作)移动到后台线程。嗨!我已经去过那里了。但我用你的密码再试了一次,但没有用。准备数据不是一个大问题,它已经存在了,我发现table.getItems().set。。。总的来说不会花那么长时间。现在,在深入挖掘之后,我发现了造成这种混乱的罪魁祸首,我一直在通过将表的prefHeightProperty绑定到列表的大小来调整表的高度,以适应其中的内容。调用本身并没有花那么长时间(尝试计时),但如果我注释掉它,它会突然变快。@84n4n4我不理解关于table.getItems().setAll(…)
需要多长时间的注释。我不是在后台线程中运行getItems().setAll(…)
,而是在后台线程完成后在FX应用程序线程中运行它。显然,即使您将表的高度绑定到项目列表的大小(我认为这不是一个足够健壮的解决方案),如果您只更改列表一次(使用setAll(…)
),而不是一次添加每个元素,这也不是问题。听起来你需要先弄清楚真正的问题是什么。抱歉搞混了。准备数据不是时间问题。在表中设置数据不是时间问题。在我的窗格中设置空表或小表不是时间问题。但是,当数据量很大时,整个系统就会崩溃。>>如果只更改列表一次(使用setAll(…),而不是一次添加每个元素,那么这也不是问题。这正是我所做的,有了它的缓慢,没有它的快速绑定。我将创建一个小示例,并尝试复制并发布到这里。@84n4n4我想如果您导致prefHeight
很大,那么您最终会强制表创建大量单元格。。。不过,这可能会以其他方式破坏布局,而且对于一个大的表,您也不需要这种解决方案。但是,由于我在滚动窗格中有一个手风琴,所以布局很有效。标题窗格也是包含表格的窗格。所以我想在侧面有两个滚动条,这就是为什么我最终使用了高度绑定。(是的,我知道,别担心,下次我不会再这样做了)非常感谢