1

This code visualises the A* algorithm. When it reaches the end of the algorithm, it pops with an alerts saying the path is found using

JOptionPane.showMessageDialog(null, "Path Found")

After clicking away the windows disappears but then gets rendered again in the top left corner without the option to close it. Also, the path to the goal is rendered after clicking away however, in the code it gets rendered before the alert appears. I am sure that the problem is in this method specifically in the way I draw or call the repaint method and not in the actual algorithm itself. Could someone please explain where I am going wrong with this?

public void paintComponent(Graphics g) {
    super.paintComponent(g);
    this.renderGrid(g);
    this.renderCloseCells(g);
    this.renderOpenCells(g);
    if (aStar.getOpenSet().size() > 0) {
        int lowestCostIndex = 0;
        for (int i = 0; i < aStar.getOpenSet().size(); i++){
            if (aStar.getOpenSet().get(i).getF() < aStar.getOpenSet().get(lowestCostIndex).getF()){
                lowestCostIndex = i;
            }
        }
        Cell current = aStar.getOpenSet().get(lowestCostIndex);
        if (aStar.getOpenSet().get(lowestCostIndex) == aStar.getEnd()){
            Cell temp = current;
            aStar.addItemPath(temp);
            while (temp.getParent() != null){
                aStar.addItemPath(temp.getParent());
                temp = temp.getParent();
            }
            System.out.println("Done");
            this.renderPath(g);
            JOptionPane.showMessageDialog(null, "Path Found");
            return;
        }
        aStar.removeCellOpenSet(current);
        aStar.addCellCloseSet(current);

        for (int i = 0; i < current.getNeighbors().size(); i++){
            Cell neighbor = current.getNeighbors().get(i);
            if (!aStar.getCloseSet().contains(neighbor)){
                int tempG = current.getG() + 1;
                if (aStar.getOpenSet().contains(neighbor)) {
                    if(tempG < neighbor.getG()){
                        neighbor.setG(tempG);
                    }
                } else {
                    neighbor.setG(tempG);
                    aStar.addCellOpenSet(neighbor);
                }
                neighbor.setH(aStar.heuristic(neighbor, aStar.getEnd()));
                neighbor.setF(neighbor.getG() + neighbor.getH());
                neighbor.setParent(current);
            }
        }

    } else {
        JOptionPane.showMessageDialog(null, "Path Not Found!");
    }
    this.repaint();
}

enter image description here enter image description here enter image description here

c0der
  • 18,467
  • 6
  • 33
  • 65
  • 3
    Never show a dialog from a painting method. Never change any object state in a painting method. paintComponent is called by Swing for all sorts of reasons, including the user moving, resizing, or deiconifying the window, or even just moving the mouse over the window. A painting method must not assume how often it will be called. And remove the call to `repaint()`—that will cause another call to paintComponent, essentially having it call itself forever. – VGR Jan 06 '20 at 02:33
  • 1
    For better help sooner, [edit] to add a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). – Andrew Thompson Jan 06 '20 at 02:39
  • Thank you, when exactly should i call the repaint method? @VGR – Alekasndr Kataev Jan 06 '20 at 19:02
  • 1
    You will want to call repaint() after you have changed the state of objects which your paintComponent reads when deciding what to paint. But remember, changes to that state, and the corresponding repaint() call, need to take place outside of any painting method. A common place for such changes is in an ActionListener of a button, or in an ActionListener of a javax.swing.Timer. – VGR Jan 06 '20 at 19:22

0 Answers0