问题
Hello guys I am working on a project where I am trying to create a maze generator.
So far I have a gird that is a 2D array of a Cell class and a JPanel that paints the grid to a JFrame and a function which uses Depth first Search to visit each Cell in the grid.
When the Cell has been visited the Cell color changes to black on the grid.
My problem is the repaint on the grid is too fast is there anyway I can slow the time or set a timer to repaint after a number of seconds. Here is the code below
import java.util.Arrays;
import java.util.Stack;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.SecureRandom;
public class Maze extends JPanel implements ActionListener {
private Cell [][] maze;
private int dims;
private Stack<Cell> S = new Stack<Cell>();
private SecureRandom num = new SecureRandom();
Timer t;
public Maze(int din)
{
dims = din;
maze = new Cell[dims][dims];
}
public void generator()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
maze[i][j] = new Cell(i,j);
}
}
}
public boolean checkAll()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
if(!maze[i][j].visited)
return false;
}
}
return true;
}
public void adjlist()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
if(i+1 >= 0 && i+1 < dims)
{
maze[i][j].neighbor.add(maze[i+1][j]);
}
if(i-1 >= 0 && i-1 < dims)
{
maze[i][j].neighbor.add(maze[i-1][j]);
}
if(j-1 >= 0 && j-1 < dims)
{
maze[i][j].neighbor.add(maze[i][j-1]);
}
if(j+1 >= 0 && j+1 < dims)
{
maze[i][j].neighbor.add(maze[i][j+1]);
}
}
}
}
public void DFS(Cell x)
{
if (!checkAll() && !maze[x.row][x.column].visited)
{
S.push(x);
System.out.println(Arrays.toString(S.toArray()));
maze[x.row][x.column].visited = true;
int randnum = num.nextInt(maze[x.row][x.column].neighbor.size());
Cell temp1 = maze[x.row][x.column].neighbor.get(randnum);
if (!maze[temp1.row][temp1.column].visited)
{
DFS(maze[temp1.row][temp1.column]);
}
else if (maze[x.row][x.column].neighbor.isEmpty())
{
S.pop();
maze[S.peek().row][S.peek().column].visited = false;
DFS(S.pop());
}
else
{
if(S.size()-1 == 0)
return;
Cell temp = null;
for (Cell c : maze[x.row][x.column].neighbor)
{
if (!maze[c.row][c.column].visited)
{
temp = c;
DFS(temp);
}
}
if (temp == null) {
S.pop();
maze[S.peek().row][S.peek().column].visited = false;
DFS(S.pop());
}
}
}
}
public void paint(Graphics g)
{
super.paint(g);
for (int row = 0; row < maze.length; row++)
{
for (int col = 0; col < maze[0].length; col++)
{
g.drawRect(35*row, 35 * col , 35, 35);
if(maze[row][col].visited)
{
//t.start();
g.fillRect(35*row, 35 * col , 35, 35);
//t.setDelay(5000);
}
}
}
repaint();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args)
{
Maze p = new Maze(10);
p.generator();
p.adjlist();
System.out.println("------------------------");
JFrame f = new JFrame();
f.setTitle("Maze");
f.add(p);
f.setVisible(true);
f.setSize(700, 700);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.DFS(new Cell(1,5));
}
@Override
public void actionPerformed(ActionEvent e) {}
}
The cell class
import java.util.ArrayList;
public class Cell{
public int row, column;
boolean visited;
ArrayList<Cell> neighbor;
public Cell(int i, int j)
{
row = i;
column = j;
visited = false;
neighbor = new ArrayList<Cell>();
}
public int getRow()
{
return this.row;
}
public int getCol()
{
return this.column;
}
public String toString()
{
return this.row + " " + this.column;
}
}
回答1:
The following code demonstrates the use of SwingWorker
to demonstrate performing long tasks (in your case dfs search) which update the gui.
Specific dfs information was removed because they are not relevant:
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
public class Maze extends JPanel {
private final Cell [][] maze;
private final int dims;
private static final int SIZE = 35;
public Maze(int dim) {
setPreferredSize(new Dimension( dim*SIZE,dim*SIZE));
dims = dim;
maze = new Cell[dims][dims];
}
public void generator()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
maze[i][j] = new Cell(i,j);
//set some arbitrary initial date
if(i%2 ==0 && j%2 ==0) {
maze[i][j].setVisited(true);
}
}
}
}
public void DFS()
{
new DFSTask().execute();
}
@Override
public void paintComponent(Graphics g) //override paintComponent not paint
{
super.paintComponent(g);
for (int row = 0; row < maze.length; row++)
{
for (int col = 0; col < maze[0].length; col++)
{
g.drawRect(SIZE*row, SIZE * col , SIZE, SIZE);
if(maze[row][col].visited)
{
g.fillRect(SIZE*row, SIZE * col , SIZE, SIZE);
}
}
}
}
public static void main(String[] args)
{
Maze p = new Maze(10);
p.generator();
JFrame f = new JFrame();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p);
f.pack();
f.setVisible(true);
p.DFS();
}
//use swing worker perform long task
class DFSTask extends SwingWorker<Void,Void> {
private static final long DELAY = 1000;
private final Random rand = new Random();
@Override
public Void doInBackground() {
dfs();
return null;
}
@Override
public void done() { }
void dfs() { //simulates long process that repeatedly updates gui
while (true){ //endless loop, just for demonstration
//update info
int row = rand.nextInt(dims);
int col = rand.nextInt(dims);
maze[row][col].setVisited(! maze[row][col].isVisited());
repaint(); //update jpanel
try {
Thread.sleep(DELAY); //simulate long process
} catch (InterruptedException ex) { ex.printStackTrace();}
}
}
}
}
class Cell{
private final int row, column;
boolean visited;
public Cell(int i, int j)
{
row = i;
column = j;
visited = false;
}
int getRow() { return row; }
int getColumn() {return column; }
boolean isVisited() { return visited; }
void setVisited(boolean visited) { this.visited = visited;}
@Override
public String toString()
{
return row + " " + column;
}
}
For more information about using SwingWorker
see doc
来源:https://stackoverflow.com/questions/50780369/grid-dfs-visualization