Java BFS Algorithm - Trying to paint nodes on JPanel

烂漫一生 提交于 2020-01-03 05:10:28

问题


I've just implemented a BFS and DFS algorithm.

My ultimate goal is to animate the algorithm onto a JPanel...

But firstly I'd like to paint the nodes to the screen in their respective parent-child relationship:

So far I've been able to achieve:

My paint component is as follows:

public void paintComponent(Graphics g) {        
    ArrayList<Nodes> nodePrintList = new ArrayList<Nodes>();    
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, width, height);

    int x = 50, y = 50;

    //if currentNode has no more children, move to next node
    g.setColor(Color.GREEN);
    g.fillRect(x, y, getRootNode().getWidth(), getRootNode().getHeight());

    g.setColor(Color.BLACK);
    g.drawString(getRootNode().getValue(),x+9, y+16);

    nodePrintList = getChildren(rootNode);  
    x-=30;  
    for (Nodes n : nodePrintList) {     
        System.out.println("\nChildren of " + rootNode.getValue() + ": " + n.getValue());
        g.setColor(Color.BLUE);
        g.fillRect(x, y+30, n.getWidth(), n.getHeight());
        g.setColor(Color.WHITE);
        g.drawString(n.getValue(),x+9, y+45);
        x+=30;
    }

}

Which gets the current children in a list for that parent by calling getChildren(Nodes n):

//need to pass a new index to getChildren once current node has no more children
public ArrayList<Nodes> getChildren (Nodes n) {
    ArrayList<Nodes> childrenList;
    childrenList = new ArrayList<Nodes>();  
    int index = nodeList.indexOf(n);
    int col = 0;
    while (col < size) {
        if (adjMatrix[index][col] == 1) {
            childrenList.add(nodeList.get(col));
        }
        col++;
    }
    return childrenList;
}

Issue:

Right now I'm hard passing the rootNode to getChildren(Node n)... so it will return all the correct nodes... But I need to pass the next node in once the current node has no more children and the list has been returned... but am struggling how to do it.

If I'm able to pass the next node in once the current node has no more children to output, I should get the representation I'm looking for.

Thanks!


UPDATED CODE:

I've attempted recursively traversing the tree and painting out the nodes...

The console output is correct...

Children of A: B
Children of A: C
Children of A: D
Children of B: E
Children of B: F
end

But the way I'm painting them is not very dynamic at all... I'm effectively adding a "tier" for each index... then an edge between them

Here is my recursive implementation using an index:

public void paintComponent(Graphics g) {
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, width, height);

    //paint initial rootNode
    g.setColor(Color.GREEN);
    g.fillRect(rootNode.getX(), rootNode.getY(), rootNode.getWidth(), rootNode.getHeight());
    g.setColor(Color.black);
    g.drawString(rootNode.getValue(), rootNode.getX()+8, rootNode.getY()+17);

    paintComponent(g, 0, new ArrayList<Nodes>());
}

//paint children
public void paintComponent(Graphics g, int index, ArrayList<Nodes> nodePrintList) { 
    Nodes currNode = nodeList.get(index);
    nodePrintList = getChildren(currNode);  

    x = currNode.getX();
    y = currNode.getY();

    //tier 1
    if (index == 0 && !nodePrintList.isEmpty()) {
        y += 50;
        x -= 100;
        color = Color.CYAN;
    }//tier 2
    else if (index == 1 && !nodePrintList.isEmpty()) {
        y += 100;
        x -= 130;
        color = Color.YELLOW;
    }
           //and would need to keep adding logic for all indices...

    //base case: no more children
    if (nodeList.indexOf(currNode)==nodeList.size()-1 && nodePrintList.isEmpty()) {
        System.out.println("\nend");
    }
    else {          
        //loop through and print all children of node n
        for (Nodes child : nodePrintList) {
            g.setColor(color);
            System.out.print("\nChildren of " + currNode.getValue() + ": " + child.getValue());
            g.fillRect(x+=50, y, child.getWidth(), child.getHeight());

            //write which node it is
            g.setColor(Color.black);
            g.drawString(child.getValue(), x+8, y+17);

            //add red edge between parent-child
            g.setColor(Color.red);
            g.drawLine(currNode.getX()+10, currNode.getY()+25, x+10, y-2);

        }
        paintComponent(g, ++index, new ArrayList<Nodes>()); 
    }
}

You can see that the Red edges are connecting appropriately from parent A to its children B, C, D, but red edges are not connecting from B to its children E and F.

Any help please!


回答1:


Here's a way to do it recursively:

public void paintComponent(Graphics g) {        
    paintComponent(g, rootNode)
}

public void paintComponent(Graphics g, Nodes curRoot) {        
    ...
    nodePrintList = getChildren(curRoot);  
    for (Nodes n : nodePrintList) {     
        System.out.println("\nChildren of " + rootNode.getValue() + ": " + n.getValue());
        ...
        paintComponent(g, n);
    }
}

However, you'll have to meddle with x and y coordinates every time you go down/up the tree, so you remember where you painted your last box on level n of the tree.

Oh and from the graphics above I see that in your graph a child node can have multiple parents (F has multiple parents), which makes the whole layouting way harder, because you'll have to remember, if a node has already been drawn (and where, if you want to draw arrows ...).



来源:https://stackoverflow.com/questions/16859559/java-bfs-algorithm-trying-to-paint-nodes-on-jpanel

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!