簡體   English   中英

在揮桿繪畫時顯示圖形

[英]Displaying graphics as they paint in swing

我為一個班級創建了一個迷宮生成器,效果很好。 唯一的事情是,我想實時顯示正在創建的迷宮,但是我已經設置了所有方法,它僅在所有計算完成后才更新。 我在代碼中使用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方法重寫

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);
            }
        }
    }

kickWalls方法將某些牆設置為null,這使得它們不會在paintComponent方法中繪制。 我在這方面還算是新手,因此,如果某些代碼質量不是很高,我深表歉意!

感謝大家。

正如MadProgrammer在評論中已經指出的那樣,幾乎可以肯定的是,您將阻止Event Dispatch Thread。 這是負責重新繪制GUI 以及處理交互事件(例如鼠標單擊和按鈕按下)的線程。

因此,大概是通過單擊按鈕開始計算,大致如下所示:

// 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組件,則必須使用SwingUtilities.invokeLater(task)將執行實際修改Swing組件的任務放回EDT。 此外,您必須確保沒有其他同步問題。 例如,線

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

仍然(必須!)由事件分發線程執行。 在這種情況下,必須確保在EDT執行第一行之后並且在執行第二行之前,沒有其他線程可以將boxes[y][x].topnull 如果這可能是您的問題,則可能需要提供更多代碼,例如,顯示在哪里以及如何修改boxes[y][x]的代碼。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM