Отображение графики, как они рисуют в разгаре

1

Я создал генератор лабиринта в качелях для класса, и он отлично работает. Единственное, что я хочу показать, что лабиринт создается в реальном времени, но так, как у меня все установлено, оно только обновляется после завершения всех вычислений. Я использую paintComponent и перекрашиваю в свой код. Как мне это показать JFrame и нарисовать линии сразу, вместо того, чтобы делать алгоритм и показывать их все в конце?

Вот соответствующий код:

 public void generateMaze() {
        Stack<Box> stack = new Stack<>();
        int totalCells = Finals.numCol * Finals.numRow, visitedCells = 1;
        Box currentCell = boxes[0][0];
        Box nextCell;
        stack.add(currentCell);

        while (visitedCells < totalCells) {
            nextCell = checkNeighbors(currentCell.xCoord, currentCell.yCoord);
            if (nextCell != null) {
                knockWalls(currentCell, nextCell);
                stack.add(currentCell);
                currentCell = nextCell;
                visitedCells++;
            } else {
                currentCell = stack.pop();
            }
        }
        repaint();
    }

Вот мой метод paintComponent override

public void paintComponent(Graphics g) {
        for(int x = 0; x < Finals.numRow; x++) {
            for(int y = 0; y < Finals.numCol; y++) {
                if(boxes[y][x].top != null)
                    boxes[y][x].top.paint(g);
                if(boxes[y][x].bottom != null)
                    boxes[y][x].bottom.paint(g);
                if(boxes[y][x].left != null)
                    boxes[y][x].left.paint(g);
                if(boxes[y][x].right != null)
                    boxes[y][x].right.paint(g);
            }
        }
    }

Метод knockWalls устанавливает определенные стены равными нулю, что заставляет их не рисоваться в методе paintComponent. Я по-прежнему довольно новичок в этом, поэтому я приношу свои извинения, если какой-то код не является супер высоким качеством!

Всем спасибо.

Теги:
arrays
swing
paintcomponent
maze

1 ответ

0
Лучший ответ

Как уже отмечал MadProgrammer в комментариях, вы почти наверняка блокируете Thread Dispatch Thread. Это поток, который отвечает за перерисовку графического интерфейса и обработку событий взаимодействия (например, щелчков мышью и нажатия кнопок).

Итак, предположим, вы начинаете вычисление с помощью нажатия кнопки, примерно так:

// The actionPerformed method of the button that
// starts the maze solving computation
@Override
void actionPerformed(ActionEvent e)
{
    generateMaze();
}

Это означает, что поток отправки событий будет занят выполнением функции generateMaze() и не сможет выполнить перерисовку.

Самое простое решение - изменить это на что-то вроде

// The actionPerformed method of the button that
// starts the maze solving computation
@Override
void actionPerformed(ActionEvent e)
{
    Thread thread = new Thread(new Runnable()
    {
        @Override
        public void run()
        {
            generateMaze();  
        }
    });
    thread.start();
}

Однако необходимо позаботиться: вы не можете изменять компоненты Swing из этого вновь созданного потока. Если вам нужно изменить компоненты Swing, вам нужно поставить задачу, которая выполняет фактическую модификацию компонента Swing на EDT, используя SwingUtilities.invokeLater(task). Кроме того, вы должны убедиться, что других проблем синхронизации нет. Например, линии

if(boxes[y][x].top != null)
    boxes[y][x].top.paint(g);

по-прежнему (и должны быть!) выполнены потоком отправки событий. В этом случае вы должны убедиться, что ни один другой поток не сможет установить boxes[y][x].top в null после того, как EDT выполнит первую строку и перед выполнением второй строки. Если это может быть проблемой в вашем случае, возможно, вам придется предоставить немного больше кода, например код, который показывает, где и как изменяются boxes[y][x].

Ещё вопросы

Сообщество Overcoder
Наверх
Меню