简体   繁体   中英

How to slow down a program execution in java?

I created a JavaFX program to draw a Sierpinski Carpet recursively, but I want to see the recursive functions in action that is, to slow down the program to see it drawing in real-time. For that I tried something like this:

public void pause(int sleepTime)
{
    try
    {
        Thread.sleep(sleepTime);
    }
    catch(InterruptedException e)
    {
        System.err.println("Error in running rotation animation!");
        System.exit(-1);
    }
}

Then I invoked this function in my drawSierpinskiCarpet function something like this:

public void drawSeripinskiCarpet(GraphicsContext gc, int x, int y, int width, int height)
{
    if(width != height || width < 3)
        return;

    int size = width /= 3;
    gc.setFill(colors[index]);
    gc.fillRect(x + size, y + size, size, size);

    index++;

    if(index == colors.length)
    {
        index = 0;
    }

    pause(1);


    for(int i = 0 ; i < 3 ; i++)
    {
        for(int j = 0 ; j < 3 ; j++)
        {
            if(i == 1 && j == 1)
            {
                continue;
            }

            drawSeripinskiCarpet(gc, x + j * size, y + i * size, size, size);
        }
    }
}

But what happens is the program hang up for a few seconds, and then directly shows up the Carpet. I'm not able to see the program in execution.

Any modification on the GUI only yields visual results after it returns. In the meantime JavaFX cannot handle any events and freezes, until your operation is done.

You can use a Timeline to execute the operation one step at a time though: Use a stack the data for one drawing execution; this allows you to do one drawing operation at a time in addition to modifying the stack for every frame of the Timeline .

@Override
public void start(Stage primaryStage) throws IOException {
    Canvas canvas = new Canvas(729, 729);
    final GraphicsContext gc = canvas.getGraphicsContext2D();

    Scene the_scene = new Scene(new StackPane(canvas));

    primaryStage.setScene(the_scene);
    primaryStage.show();

    final Color[] colors = new Color[] { Color.BLUE, Color.ORANGE, Color.GREEN, Color.RED, Color.BROWN,
            Color.MAGENTA, Color.YELLOW, Color.CYAN, Color.BLACK };
    class IndexHolder {
        int index = 0;

        Color getNextFill() {
            Color fill = colors[index];
            ++index;
            if (index >= colors.length) {
                index = 0;
            }
            return fill;
        }
    }
    final IndexHolder indexHolder = new IndexHolder();

    class StackEntry {
        int x;
        int y;
        int size;

        public StackEntry(int x, int y, int size) {
            this.x = x;
            this.y = y;
            this.size = size;
        }

        void executeStep(List<StackEntry> stack, IndexHolder indexHolder, GraphicsContext gc) {
            int size = this.size /= 3;
            gc.setFill(indexHolder.getNextFill());
            gc.fillRect(x + size, y + size, size, size);

            if (size >= 3) {
                // add new "calls" in reverse order here
                // (first call in original needs to be popped from the stack first)
                for (int i = 2; i >= 0; --i) {
                    for (int j = 2; j >= 0; --j) {
                        if (i == 1 && j == 1) {
                            continue;
                        }

                        stack.add(new StackEntry(x + j * size, y + i * size, size));
                    }
                }
            }
        }
    }

    // finally create the animation
    final List<StackEntry> stack = new ArrayList<>();
    stack.add(new StackEntry(0, 0, (int) canvas.getHeight()));

    final Timeline timeline = new Timeline();
    timeline.setCycleCount(Animation.INDEFINITE);
    timeline.getKeyFrames().add(new KeyFrame(Duration.millis(1),
            evt -> {
                // pop
                StackEntry entry = stack.remove(stack.size() - 1);

                entry.executeStep(stack, indexHolder, gc);
                if (stack.isEmpty()) {
                    timeline.stop();
                }
            }));

    timeline.play();

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM