user13306076
user13306076

Reputation:

Draw shapes with delay

I know there are already hundreds of threads but I just cant understand it.. I have this very simple class thats drawing a grid. I would like to add like a 0.2 second delay after each square. Thread.sleep doesnt work. What is the simplest way?

    public Screen() {
        repaint();
    }
    public void paint(Graphics g) {

        for(int i = 0; i < 9; i++) {
            for(int j = 0; j < 9; j++) {
                g.drawRect(50 * i, 50 * j, 50, 50);
                //Add delay
            }
        }
    }

Upvotes: 0

Views: 295

Answers (1)

Frakcool
Frakcool

Reputation: 11153

The simplest way to achieve delayed drawing is by using a Swing Timer, which is a class that won't block the EDT when executed. This will allow you to create a delay without blocking your UI (and making everything appear at once).

You'll have a single JPanel that's going to handle the painting in the paintComponent(...) method and not paint(...) as you did in your code above. This JPanel will repaint every Rectangle shape from the Shape API.

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;

public class DelayedDrawing {
    private JFrame frame;
    private JPanel pane;
    private Timer timer;
    private int xCoord = 0;
    private int yCoord = 0;
    private static final int GAP = 10;
    private static final int WIDTH_HEIGHT = 10;
    private static final int ROWS = 5;
    private static final int COLS = 5;

    private List<Rectangle> rectangles;

    @SuppressWarnings("serial")
    private void createAndShowGUI() {
        //We create the JFrame
        frame = new JFrame(this.getClass().getSimpleName());
        //We create a list of Rectangles from the Shape API
        rectangles = new ArrayList<>();
        createRectangle();

        //Creates our JPanel that's going to draw every rectangle
        pane = new JPanel() {
            //Specifies the size of our JPanel
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(150, 150);
            }

            //This is where the "magic" happens, it iterates over our list and repaints every single Rectangle in it
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g;
                for (Rectangle r : rectangles) {
                    System.out.println(r.x + " " + r.y);
                    g2d.draw(r);
                }
            }
        };

        //This starts our Timer
        timer = new Timer(200, listener);
        timer.setInitialDelay(1000);
        timer.start();

        //We add everything to the frame
        frame.add(pane);
        frame.pack();
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    //Creates a new Rectangle and adds it to the List
    private void createRectangle() {
        Rectangle r = new Rectangle(xCoord * WIDTH_HEIGHT + GAP, yCoord * WIDTH_HEIGHT + GAP, WIDTH_HEIGHT, WIDTH_HEIGHT);
        rectangles.add(r);
    }

    //This will be executed everytime the Timer is fired
    private ActionListener listener = e -> {
        if (xCoord < ROWS) {
            if (yCoord < COLS) {
                yCoord++;
            } else {
                yCoord = 0;
                xCoord++;
                if (xCoord == ROWS) {
                    timer.stop();
                    return;
                }
            }
        }
        createRectangle();
        pane.repaint();
    };

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new DelayedDrawing()::createAndShowGUI);
    }
}

enter image description here

Upvotes: 3

Related Questions