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