Refreshing a JavaFX GUI

后端 未结 1 1862
无人共我
无人共我 2021-01-28 01:14

I am attempting to create a program to simulate a solve of a Rubik\'s Cube using Java and JavaFX. The scene has a text box that will show every move the computer makes in proper

1条回答
  •  孤街浪徒
    2021-01-28 01:33

    You don't see the effect until the end because you are executing everything on the FX Application Thread. This is the same thread that is responsible for rendering the UI, so if some action (such as your SolveClicked [sic: please use proper naming conventions] method) is performed on that thread, the UI cannot be rendered until the action is complete.

    If you think about this the right way, what you are really trying to do is create an animation. (You don't just want to show the solution; you want to show multiple "animation frames" to the user, each of which represents a step in the solution.) So you should use the animation API. The simplest way might be a Timeline:

    @FXML
    protected void solveClicked(ActionEvent event) {
        Timeline timeline = new Timeline(
            new KeyFrame(Duration.millis(500), e -> L()),
            new KeyFrame(Duration.millis(1000), e -> R()),
            new KeyFrame(Duration.millis(1500), e -> F()),
            new KeyFrame(Duration.millis(2000), e -> B()));
        timeline.play();
    }
    

    If you need a more "automated" way of generating the timeline, you can do (fun) things like:

    @FXML
    protected void solveClicked(ActionEvent event) {
        Runnable[] steps = new Runnable[] {this::L, this::R, this::F, this::B};
        createTimeline(steps, 500).play();
    }
    
    private Timeline createTimeline(Runnable[] steps, int delay) {
        Duration frameTime = Duration.millis(delay);
        Duration increment = Duration.millis(delay);
        Timeline timeline = new Timeline() ;
        for (Runnable step : steps) {
            timeline.getKeyFrames().add(new KeyFrame(frameTime, e -> step.run()));
            frameTime = frameTime.add(increment);
        }
        return timeline ;
    }
    

    A more sophisticated approach might be to represent each move of a face by an animation (showing the actual rotation), and then combine them all into a SequentialTransition.

    0 讨论(0)
提交回复
热议问题