JavaFx 在方法完成后冻结

JavaFx freezes after method is done

我的问题是我的 JavaFx 应用程序变得非常慢。在应用程序启动和某些触发事件中。这是一个使用 GridPane 的日历应用程序,我正在修改它。我有这个方法:

t.setOnMouseClicked(event->{

        long starttid = System.currentTimeMillis();
        System.out.println("start");
        if (markedTimeEnd != null && markedTimeStart != null) {
            colorMinutes(markedTimeStart, markedTimeEnd, Color.BLACK, bakrundWhite);
        } else if (markedTimeStart != null) {
            colorMinutes(markedTimeStart, markedTimeStart, Color.BLACK, bakrundWhite);
        }

        long tidNu = System.currentTimeMillis();
        long tid = tidNu-starttid;
        System.out.println("Print first time:\n"+tid);

        int minutTid = gridPane.getRowIndex(t);
        int timmeTimme = minutTid / 60;
        int minutMinut = minutTid - (60 * timmeTimme);
        markedTimeStart = new TidPunkt(timmeTimme, minutMinut);
        markedTimeEnd = null;

        tid = System.currentTimeMillis() -tidNu;
        tidNu = System.currentTimeMillis();
        System.out.println("Time for the middel calculations:\n"+tid);
        if (markedTimeEnd != null && markedTimeStart != null) {
            colorMinutes(markedTimeStart, markedTimeEnd, Color.GREEN,bakrundGren);
        } else if (markedTimeStart != null) {
            colorMinutes(markedTimeStart, markedTimeStart, Color.GREEN,bakrundGren);
        }
        event.consume();
        repaintAll();
        System.out.println("Time to end:\n"+(System.currentTimeMillis()-tidNu));
    });

以及 colorMinutes 的代码:

    private void colorMinutes(TidPunkt markedTimeStart, TidPunkt markedTimeEnd, Color colorText, Background colorOther) {

    System.out.println("The call is comming");

    int startBothTogether = markedTimeStart.getTimme() * 100 + markedTimeStart.getMinut();
    int endBothTogether = markedTimeEnd.getTimme() * 100 + markedTimeEnd.getMinut();

    System.out.println("Befor filter");
    gridPane.getChildren().stream()//parallelStream()
        .filter(x-> x.getId()!=null)
        .filter(y-> y.getId().matches("\d\d:\d\d"))
        .filter(pp->{
            int hoursForPart = Integer.parseInt(((Node) pp).getId().split(":")[0]);
            int miutesForPart = Integer.parseInt(((Node) pp).getId().split(":")[1]);
            int bothTogether = hoursForPart * 100 + miutesForPart;
            if (bothTogether >= startBothTogether && bothTogether <= endBothTogether)
                return true;
            else 
                return false;
        })
        .forEach(pp->{
            Platform.runLater(() -> {
                System.out.println("Changing collor ----");
                if(pp instanceof Pane){
                    ((Pane) pp).setBackground(colorOther)
                }else{
                    ((Text) pp).setFill(colorText);
                }
            });
        });
}

但是它需要很长时间才能显示在屏幕上,并且在我可以看到 System.out.println 完成这些方法后的某个时候它会冻结。我一直在尝试分析但无法弄清楚(最好的是我想出了它似乎是退出方法时 javaFx "stuff" 的一个大调用树)。 System.out.println 打印出来的是:

start
Print first time:
0
Time for the middel calculations:
0
The call is comming
Befor filter
Time to end:
373
Changing collor ----
Changing collor ----
Changing collor ----
Changing collor ----

但是从按下按钮到所有颜色都正确需要很多秒。

可以找到完整代码here

您使用 Platform.runLater 向许多 Runnable 发帖。根本没有理由在这里使用 Platform.runLater,因为 onMouseClicked 事件处理程序无论如何都是在 javafx 应用程序线程上执行的。

正在使用

.forEach(pp->{
    if(pp instanceof Pane){
        ((Pane) pp).setBackground(colorOther)
    }else{
        ((Text) pp).setFill(colorText);
    }
});

应该会大大提高性能。

此外,您似乎在 repaintAll 方法(更具体地说是 ritaGrundKalender 方法)中添加了大量 Nodes 而没有删除 Nodes,这增加了每次点击的 Runnable 秒数。我建议你改变这种行为。