在调试应用程序时,我希望主线程在每个Runnable之后等待我使用的JavaFX事件队列
Platform.runLater(new Runnable()... )
等到它被执行(即可见) . 但是这里有两个曲折:
首先,它不是一个标准的,GUI驱动的JavaFX应用程序 . 它是一个显示和更新JavaFX阶段的脚本 . 所以结构看起来像这样:
public static void main(String [] args){
//do some calculations
SomeView someView = new SomeView(data); //SomeView is basically a wrapper for a stage
PlotUtils.plotView(someView) //displays SomeView (i.e. the stage)
//do some more calculations
someView.updateView(updatedData)
//do some more calculations
}
public class SomeView {
private static boolean viewUpdated = false;
private ObservableList<....> observableData;
public void updateView(Data data){
Platform.runLater(new Runnable() {
@Override
public void run() {
observableData.addAll(data);
boolean viewUpdated = true;
}
});
//If configured (e.g using boolean switch), wait here until
//the Runnable has been executed and the Stage has been updated.
//At the moment I am doing this by waiting until viewUpdated has been
//set to true ... but I am looking for a better solution!
}
}
其次,应该很容易禁用这个“功能”,即等待Runnable被执行(使用当前的方法这是没有问题的,但也可以使用替代方法) .
做这个的最好方式是什么?
例如 . 有什么像阻塞版本在JavaFX线程上执行Runnable或有一个简单的方法来检查事件队列上的所有事件是否已执行/事件队列是否为空....?
2 回答
这是基于JavaFX2: Can I pause a background Task / Service?的总体思路
基本的想法是提交
FutureTask<Void>
到Platform.runLater()
,然后在FutureTask
上调用get()
.get()
将阻止,直到任务完成:你 must not 在FX应用程序线程上执行此代码块,因为这将导致死锁 .
如果您希望这可以轻松配置,您可以执行以下操作:
现在在您的应用程序中,您可以:
并用
frontExec.execute(...);
替换所有对Platform.runLater(...)
的调用根据您想要的配置方式,您可以根据命令行参数或属性文件有条件地创建
frontExec
(或者,如果您使用依赖注入框架,则可以注入它) .还有
PlatformImpl.runAndWait()
使用倒计时锁存器,只要你不从JavaFX线程调用它