方法完成后,JavaFx会冻结

时间:2017-01-01 15:47:35

标签: java performance javafx freeze

我的问题是我的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&#34;东西&#34;退出方法时)。 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

1 个答案:

答案 0 :(得分:1)

您使用Platform.runLater发布了许多Platform.runLater个帖子。这里没有理由使用onMouseClicked,因为.forEach(pp->{ if(pp instanceof Pane){ ((Pane) pp).setBackground(colorOther) }else{ ((Text) pp).setFill(colorText); } }); 事件处理程序无论如何都会在javafx应用程序线程上执行。

使用

Node

应该大幅改善表现。

此外,您似乎在repaintAll方法(更具体地说是ritaGrundKalender方法)中添加了大量的Node s而未删除Runnable s,这会增加//Main public class Main { public static void main(String[] args) throws InterruptedException { Connector connector = new Connector(); connector.createSomeTask("started",(response, error)->{ }); } } //Connector Class import java.util.function.BiConsumer; public class Connector { static String taskStage = null; public void createSomeTask(final String taskName, final BiConsumer<ServerResponse, ServerError> consumer) { createSomeTask(taskName, true, consumer); } private void createSomeTask(final String taskName, boolean retry, final BiConsumer<ServerResponse, ServerError> consumer) { updateTaskStage((newStage, error)->{ if(error!=null) { if (retry) { createSomeTask(taskName, false, consumer); //The 'recursive' retry call return; } else { consumer.accept(null, error);//only after second failure return; } } consumer.accept(new ServerResponse(),null); }); } //re-uses existing task or starting a new one when the current is null / failed private void updateTaskStage(final BiConsumer<String, ServerError> consumer) { if(taskStage ==null || taskStage != "failed") consumer.accept(taskStage,null); else { taskStage = "started"; consumer.accept(taskStage,null); } } class ServerResponse{} class ServerError{} } 每次点击都{{1}}。我建议你改变这种行为。