在GUI线程繁重的工作中显示ProgressIndicator

问题描述:

在javafx ui线程中完成一些繁重的工作时,是否可以显示(旋转,未卡住)进度指示器?在GUI线程繁重的工作中显示ProgressIndicator

Backstory: 我必须加载一个相当大的tableView到一个TitledPane(需要几秒钟)。使整个事情滞后的命令是TitledPane.setContent(myTableView)。 所以我想在这段时间至少显示一些加载动画或指标。

所以现在即时通讯执行以下操作,给UI线程足够的空间来呼吸做昂贵的调用之前显示我的加载动画:

showMyLoadingAnimation(); 
PauseTransition pause = new PauseTransition(Duration.seconds(1)); 
pause.setOnFinished(event -> { 
    setContent(myTableView); 
}); 
pause.play(); 
dismissMyLoadingAnimation(); 

这个作品得到显示的进度指示器,但一旦UI线程开始工作setContent它卡住了。我看到有些人使用swing来显示平移或对话的动画只是为了让它在不同的线程中运行并且没有卡住,但还没有找到一个有说服力的解决方案。

编辑: 好的,我发现问题的根源。 所以我得到的表prefHeightProperty绑定到它显示的列表大小,如下所示:JavaFX - Adapt TableView height to number of rows 在那个星期前做了,工作,忘记了它。

花费很多时间。所以虽然在设置绑定时计时调用并不表明需要大量时间,但当表变得越来越大时,ui线程似乎遇到了大问题。

感谢詹姆斯,他的回答对大多数遇到这种问题的人来说是正确的。

可有人请评论这个问题在那里:JavaFX - Adapt TableView height to number of rows (因为这是第一个问题,我没有足够的代表尚未就此发表评论。)在Task

+0

'titledPane.setContent(myTableView);'实际上不可能采取任何可观的时间。代码中发生的其他事情正在花时间;可能会加载数据。您应该将耗时的工作(这不是实际的UI工作)转移到后台线程。 –

加载数据,在后台线程中运行。在启动任务时显示加载动画(或ProgressIndicator等),并在任务完成时将其删除。

的基本思路是这样的:

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(); 
+0

嗨! 我已经在那里。但我用你的代码再次尝试,但无济于事。 准备数据不是一个大问题,它已经存在了,我发现table.getItems()。set ...并不需要那么长时间。 现在深入挖掘后,我发现这混乱的罪魁祸首,我一直在调整表的高度,以适应内容与此http://*.com/questions/27945817/javafx-adapt-tableview-height-to-number-通过将表的prefHeightProperty绑定到列表的大小来创建行 。 呼叫本身并没有花费那么长时间(尝试计时),但是如果我将它评论为突然很快。 – 84n4n4

+0

@ 84n4n4我不明白'table.getItems()。setAll(...)'需要多长时间。我没有在后台线程中运行'getItems()。setAll(...)',我在后台线程完成后在FX应用程序线程上运行它。显然,即使你将表的高度与项目列表的大小绑定在一起(我认为这不是一个足够强大的解决方案),如果你仅仅改变一次列表(用'setAll(。 ..)')而不是每次添加每个元素,这也不是问题。听起来你需要弄清楚实际问题是什么。 –

+0

对于混淆感到抱歉。准备数据不是时间问题。设置表中的数据不是时间问题。在我的窗格中设置一个空的或小的表格不是时间问题。 但是当拥有大量数据的时候整个事情就会崩溃。 >>如果您只更改列表一次(使用setAll(...)),而不是一次添加每个元素,那也不是问题。 这正是我在做的事情,与prefHeight绑定它的速度很慢,没有它的速度。 我会破解一个小例子,并尝试在这里复制并发布它。 – 84n4n4