java在加载/显示FXML时避免动画中的短暂停顿
加载新的FXML并设置边框窗格的中心时,应用程序会短暂“冻结”,现有动画(无论是来自时间轴还是图像视图中的gif)将停止。我正在使用以下代码更改centerView:
@FXML
public void handleChangeView(ActionEvent event) {
Task<Parent> loadTask = new Task<>() {
@Override
public Parent call() throws IOException {
String changeButtonID = ((ToggleButton) event.getSource()).getId();
Parent newOne = getFxmls().get(changeButtonID);
if (newOne == null) {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/view/" + changeButtonID + ".fxml"));
newOne = loader.load();
getFxmls().put(changeButtonID, newOne);
}
return newOne ;
}
};
loadTask.setOnSucceeded(e -> {
getMainUI().setCenter(loadTask.getValue());
});
loadTask.setOnFailed(e -> loadTask.getException().printStackTrace());
Thread thread = new Thread(loadTask);
thread.start();
}
虽然这可以在加载时间内保持UI的响应性,但当中间阶段第一次显示时,会出现明显的延迟。查看CPU配置文件:
我不确定延迟是来自初始化函数的运行,还是元素的加载。这是程序的gif,你可以看到可见的延迟:
通过在VLC中加载并逐帧进行升级,在30 fps的视频中,延迟看起来是5或6帧,这意味着大约200毫秒的延迟,这意味着动画冻结超过50毫秒左右的初始化方法。(可能整个加载方法会冻结动画?)
问题是,在这个过程中是否可以保持动画平滑
//*******编辑**********//
所以我完成了这个项目,删掉了尽可能多的方法和类,把整个游戏减少到了6个最小类。我仍然延迟按下字符按钮(“你”按钮)。举了这么一个小小的例子,我对可能的错误一无所知。我已经把这个上传到了谷歌硬盘上,供大家看看
https://drive.google.com/open?id=17A-PB2517bPJc8Dek-yp2wGXsjTyTj1d
# 1 楼答案
你的代码没有任何“错误”(至少在这个问题上)
您遇到的问题也与FXML的加载无关(FXML的加载速度非常慢,并且您已经正确地处理了FX线程之外的问题)
口吃的发生有以下原因:
character.fxml
中相对较大的层次结构main.css
你会注意到;口吃稍微不那么突出)每次用某个大节点替换
mainView
的center
时,它都会导致JavaFx运行时完全重新布局并重新设置(至少)该节点的样式。这发生在FX线程上,因此你会注意到口吃一种可能的缓解方法是一种经典的游戏开发技术:尽可能多地预分配。 只需在启动期间加载所有必要的FMXLs一次,并将其放入场景图中即可。然后,在单击处理程序中,更改要显示/隐藏的节点的可见性或(Z-)位置。 例如,这是一个很好的
StackPane
用例我对您的代码进行了一些修改,以演示我的意思: Prototype
查看以下资源了解更多信息: