【问题标题】:JavaFx freezes after method is done方法完成后 JavaFx 冻结
【发布时间】:2017-05-15 23:03:55
【问题描述】:

我的问题是我的 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“东西”)。 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

【问题讨论】:

  • 网格窗格中有多少个窗格?
  • 我最近一次测试时大约为 7200,但这取决于所以可以降至大约 2800。

标签: java performance javafx freeze


【解决方案1】:

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

使用

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

应该大大提高性能。

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

【讨论】:

  • 很好,确实有帮助,谢谢!但是一个奇怪的事情是,第一次按下一个对象需要一些时间才能变成绿色,但第二次是立即完成,你有什么想法来解决这个问题吗?
  • 通过在创建它们时添加背景来解决它。
猜你喜欢
  • 2016-10-07
  • 2016-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多