JavaFX矩形不';t更新

JavaFX矩形不';t更新,java,animation,javafx,thread-sleep,Java,Animation,Javafx,Thread Sleep,我想用细胞自动机做一个迷宫分解器,但我有一个显示问题 对于新一代的自动机网格,我们尝试以矩形的形式显示单元。初始化工作正常,网格显示,最后一代模拟也显示,但中间步骤不显示。 第一代图片 上一代 //初始化矩形列表 public void initRectList(){ 对于(int height=0;height

我想用细胞自动机做一个迷宫分解器,但我有一个显示问题 对于新一代的自动机网格,我们尝试以矩形的形式显示单元。初始化工作正常,网格显示,最后一代模拟也显示,但中间步骤不显示。

第一代图片

上一代

//初始化矩形列表
public void initRectList(){
对于(int height=0;height
公共类MazeFX{
私有HBox根=新HBox();
私有场景=新场景(根,1100800);
private TilePane TilePane=新TilePane();
专用电网=新电网(30,30);
私有矩形[][]矩形列表=新矩形[30][30];
专用VBox按钮=新建VBox();
专用按钮重置=新按钮(“重置”);
私人按钮pas=新按钮(“播放”);
专用按钮加载=新按钮(“加载”);
私人马祖托马扎;
私人最终双记录高度=20。;
私人最终双记录宽度=20。;
公共MazeFX(Stage)抛出InterruptedException{
scene.getStylesheets().add(getClass().getResource(“/src/application.css”).toExternalForm());
initButton();
initLayout();
initGridByTopologie();
mazeA=新Mazeutomon(this.grid);
initRectList();
drawGrid();
按下按钮(舞台);
设置窗口(阶段);
显示窗口(舞台);
}
要开始下一代,您只需按下一个按钮

//布顿河畔利用行动
公共无效按下按钮(舞台){
按Reset();
按pas();
压力加载(阶段);
}
//Boutton Play/Stop préssé
公共图书馆{
此.pas.setonMouseClacked(e->{
对于(int i=0;i<30;i++){
mazeA.nextStep();
试一试{
睡眠(100);
}捕获(中断异常中断异常){
interruptedException.printStackTrace();
}
updateRectColor();
}
}
);
}

问题似乎是我们被困在方法setOnMouseClicked()中,矩形的更新没有完成,通过文本显示,我看到了自动机的演变,这表明模拟工作正常,问题似乎来自JavaFX,JavaFX应用程序线程作为循环运行(实际的实现细节要复杂得多)该循环执行以下操作(伪代码):

默认情况下,JavaFX每秒最多渲染60次场景

事件处理程序中的代码在FX应用程序线程上执行(由上面伪代码循环中的第一个块调用)。由于它在该线程上休眠,FX应用程序线程永远不会到达循环的第三部分(渲染场景)直到整个事件处理程序完成。因此,您永远不会看到中间更新,因为场景从未渲染

假设
mazeA.nextStep()
不阻塞(或运行时间较长),最好将其重构为
动画
,例如
时间线

public void pressPAS() {

    this.pas.setOnMouseClicked(e -> {
        KeyFrame updateMaze = new KeyFrame(Duration.ZERO, evt -> mazeA.nextStep());
        KeyFrame updateRect = new KeyFrame(Duration.millis(100), evt -> updateRectColor());
        Timeline timeline = new Timeline(updateMaze, updateRect);
        timeline.setCycleCount(30);
        timeline.play();
    });
}

timeline.play()
方法只需启动动画并立即返回,允许FX应用程序线程继续。当FX应用程序线程检查是否有正在运行的动画时,它将检查是否需要执行关键帧中的任何一个处理程序,如果需要,它将执行这些处理程序。然后它将像往常一样渲染场景。

永远不要在F上睡觉X应用程序线程。对此类功能使用
暂停转换
时间线
。谢谢。我已经找了3天了。我用a和b替换了e,因为已经声明了e。
public void pressPAS() {

    this.pas.setOnMouseClicked(e -> {
        KeyFrame updateMaze = new KeyFrame(Duration.ZERO, evt -> mazeA.nextStep());
        KeyFrame updateRect = new KeyFrame(Duration.millis(100), evt -> updateRectColor());
        Timeline timeline = new Timeline(updateMaze, updateRect);
        timeline.setCycleCount(30);
        timeline.play();
    });
}