Java - 将树节点绘制到 JPanel 上

标签 java algorithm swing jpanel

我正在尝试以递归方式将树的所有节点绘制到 JPanel 上。

它应该是这样的:

enter image description here

其中,BCDA 的子级。

并且,EFB 的子级

父子关系的输出是准确的:

PARENT: A | x,y: 180, 100...
 CHILD: B | x,y: 205, 150
PARENT: B | x,y: 205, 150...
 CHILD: E | x,y: 230, 200
PARENT: B | x,y: 205, 150...
 CHILD: F | x,y: 230, 200
end
PARENT: A | x,y: 180, 100...
 CHILD: C | x,y: 205, 150
PARENT: A | x,y: 180, 100...
 CHILD: D | x,y: 205, 150

但是 x, y 坐标不是...每个 child 的 x 位置都与另一个 child 的位置重叠...所以它只显示每个父节点的 1 个子节点:

enter image description here

我认为我必须做的是找到一种方法来为每个新的子行递增一次 y...并为父项的每个子递增 x 所以它们很好地排成一行……但是节点的坐标正在重置。

有什么想法吗?

代码:

public void paintComponent(Graphics g) {
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, width, height);
    g.setColor(Color.CYAN);
    g.fillRect(rootNode.getX(), rootNode.getY(), rootNode.getWidth(), rootNode.getHeight());
    paintComponent(g, rootNode);

}

public void paintComponent(Graphics g, Nodes parentNode) {  
    //keep generating new nodePrintList to load with new Children
    ArrayList<Nodes> nodePrintList = new ArrayList<Nodes>();    

    //base case: end of nodeList
    if (nodeList.indexOf(parentNode)==nodeList.size()-1) {
        System.out.println("\nend");
    }
    else {  
    //traverse nodeList recursively 
        nodePrintList = getChildren(parentNode);    
        //loop through and print all children of node n
        System.out.println();

        for (Nodes child : nodePrintList) {             
            g.setColor(Color.GREEN);
            child.setX(parentNode.getX()+25);
            child.setY(parentNode.getY()+50);
            g.fillRect(child.getX(), child.getY(), child.getWidth(), child.getHeight());
            System.out.print("PARENT: " + parentNode.getValue() + " | x,y: " + parentNode.getX() + ", " + parentNode.getY() + "...\n CHILD: " + child.getValue() + " | x,y: " + child.getX() + ", " + child.getY());    
            paintComponent(g, child);
        }           
    }
}

getChildren() 方法返回每个父级的子级列表:

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

最佳答案

主要问题似乎出在 paintComponent 方法中的 for 循环中。在这里,您为每个 child 使用相同的 x 坐标。你可以这样修复它:

int x = parentNode.getX()+25; // x position of first child
for (Nodes child : nodePrintList) {
    child.setX(x);
    child.setY(parentNode.getY()+50); // y position is same for each child
    // [...] fill rect, print, recursive call, etc.
    x -= 50; // in each iteration, move nodes further to the left
}

然而,这只是一个问题。另一个问题是,为了正确布置节点,您必须考虑每个分支的总宽度。解决这个问题的一种方法是返回每个分支的总宽度,让 paintComponent(g, nodes) 返回 x,并将它(加上一些偏移量)用于下一个 child 。上面的代码可能看起来像这样:

int x = parentNode.getX()+25; // x position of first child
for (Nodes child : nodePrintList) {
    child.setX(x);
    child.setY(parentNode.getY()+50); // y position is same for each child
    // [...] fill rect, print, etc.
    x = paintComponent(g, child) - 50; // next x is left of the total width of the child
}
return x; // return x (change methods signature accordingly)

这可能还需要一些修改,但它应该能给您思路。

关于Java - 将树节点绘制到 JPanel 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17198234/

相关文章:

java - wcf 互操作 : No timestamp is available in security header to do replay detection

java - Dijkstra 算法的文件输入

ruby - 通过任意查询查找项目

java - 无法更改布局边框颜色

java - 基于Windows的应用程序通过JAVA中的变量访问对象

Java相机实现

python - 如何并行洗牌大量项目,python

algorithm - 渐近符号比较

java - JTextField/JTextComponent 中的选择有限?

java - InputVerifier 和多个字段