Home > Enterprise >  Create Delay within GUI in Java
Create Delay within GUI in Java

Time:09-17

I am trying to visualize a Maze-Generator and i don't know how i can make a delay everytime a Cell/Node is visited. I have read that you shouldn't use Thread.sleep() in a GUI application because it messes with the event dispatch Thread, so i tried utilizing the Swing.Timer, however this also did'nt work out for me. Everytime i tried it, the program just froze and the Window that popped up was blank.

This is the GUI-Class which i use to visualize each step of the Path-finding-Method:

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GUI extends JPanel{
    static int frameWidth = 1920;
    static int frameHeight = 1080;
    Timer timer;
    int CELL_SIZE = 30;
    int STROKE_WIDTH = 4;
    int x = 60;
    int y = 30;
    boolean solve = false;
    MazeWilson m;

    public GUI() {
        timer = new Timer(1000,this);
        timer.start();
        m = new MazeWilson(x, y);
        m.generatePath();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        this.setBackground(Color.WHITE);
        Graphics2D g2 = (Graphics2D) g;
        g2.setStroke(new BasicStroke(STROKE_WIDTH));
        g2.setColor(Color.BLACK);
        for (int i = 0; i < m.height; i  ) {
            for (int j = 0; j < m.width; j  ) {
                g2.drawRect(10   CELL_SIZE * j, 10   CELL_SIZE * i, CELL_SIZE, CELL_SIZE);
            }
        }
        g.setColor(Color.WHITE);
        for (int i = 0; i < m.height; i  ) {
            for (int j = 0; j < m.width; j  ) {
                if (!m.field[i][j].walls[0]) {
                    g2.drawLine(10   STROKE_WIDTH   CELL_SIZE * j, 10   CELL_SIZE * (i   1), 10 - STROKE_WIDTH   CELL_SIZE * (j   1), 10   CELL_SIZE * (i   1));
                }
                if (!m.field[i][j].walls[1]) {
                    g2.drawLine(10   CELL_SIZE * j, 10   STROKE_WIDTH   CELL_SIZE * i, 10   CELL_SIZE * j, 10 - STROKE_WIDTH   CELL_SIZE * (i   1));
                }
                if (!m.field[i][j].walls[2]) {
                    g2.drawLine(10   STROKE_WIDTH   CELL_SIZE * j, 10   CELL_SIZE * i, 10 - STROKE_WIDTH   CELL_SIZE * (j   1), 10   CELL_SIZE * i);
                }
                if (!m.field[i][j].walls[3]) {
                    g2.drawLine(10   CELL_SIZE * (j   1), 10   STROKE_WIDTH   CELL_SIZE * i, 10   CELL_SIZE * (j   1), 10 - STROKE_WIDTH   CELL_SIZE * (i   1));
                }
            }
        }

        if (solve) {
            drawSolution(g2);
        }
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("Maze");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        GUI g = new GUI();
        f.add(g);
        JButton solveMaze = new JButton("Lösen");
        solveMaze.setFont(new Font("Arial", Font.PLAIN, 40));
        solveMaze.setPreferredSize(new Dimension(30, 30));
        solveMaze.setBackground(Color.GREEN);
        solveMaze.setOpaque(true);
        f.add(solveMaze, BorderLayout.SOUTH);
        f.setExtendedState(JFrame.MAXIMIZED_BOTH);
        f.getContentPane().setBackground(Color.BLACK);
        f.setVisible(true);
        f.toFront();
    }

    public void drawSolution(Graphics g) {
        Cell c = m.findPath();
        g.setColor(Color.CYAN);
        for (; c.parent != null; c = c.parent) {
            g.fillRect(10   STROKE_WIDTH/2   c.x * CELL_SIZE, 10   STROKE_WIDTH/2   c.y * CELL_SIZE, CELL_SIZE - STROKE_WIDTH, CELL_SIZE - STROKE_WIDTH);

            switch (c.parent.y - c.y) {
            case 1: {
                g.fillRect(10   STROKE_WIDTH/2   c.x * CELL_SIZE, 10   STROKE_WIDTH/2   c.y * CELL_SIZE, CELL_SIZE - STROKE_WIDTH, CELL_SIZE   CELL_SIZE/4 - STROKE_WIDTH);
                break;
            }
            case -1: {
                g.fillRect(10   STROKE_WIDTH/2   c.x * CELL_SIZE, 10   STROKE_WIDTH/2   c.parent.y * CELL_SIZE, CELL_SIZE - STROKE_WIDTH, CELL_SIZE   CELL_SIZE/4 - STROKE_WIDTH);
                break;
            }
            }
            switch (c.parent.x - c.x ) {

                case 1: {
                    g.fillRect(10   STROKE_WIDTH/2   c.x * CELL_SIZE, 10   STROKE_WIDTH/2   c.y * CELL_SIZE, CELL_SIZE   CELL_SIZE/4 - STROKE_WIDTH, CELL_SIZE - STROKE_WIDTH);
                    break;
                }
                case -1: {
                    g.fillRect(10   STROKE_WIDTH/2   c.parent.x * CELL_SIZE, 10   STROKE_WIDTH/2   c.y * CELL_SIZE, CELL_SIZE   CELL_SIZE/4 - STROKE_WIDTH, CELL_SIZE - STROKE_WIDTH);
                    break;
                }
            }
        }
        g.fillRect(10   STROKE_WIDTH/2   c.x * CELL_SIZE, 10   STROKE_WIDTH/2   c.y * CELL_SIZE, CELL_SIZE - STROKE_WIDTH, CELL_SIZE - STROKE_WIDTH);

    }
}

The generatePath-Method generates the maze and the findPath-Method solves the maze. I want the drawSolution-function to have a delay in each iteration, so that it progressively shows each Cell that is visited during the process.

CodePudding user response:

Swing is a single Thread library. All painting tasks are executed by the enter image description here

  • Related