繁体   English   中英

Java-将树节点绘制到JPanel上

[英]Java - Paint tree nodes onto JPanel

我试图递归地将树的所有节点绘制到JPanel上。

它看起来应该像这样:

在此处输入图片说明

其中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坐标不是...每个孩子的x位置与另一个孩子的x位置重叠...因此,每个父对象仅显示1个孩子节点:

在此处输入图片说明

我想我要做的就是找到一种方法,每增加一行新的孩子就增加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循环中。 在这里,您为每个孩子使用相同的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 ,并将其(加上一些偏移量)用于下一个子级。 上面的代码可能看起来像这样:

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)

这可能仍需要进行一些修改,但是应该可以给您带来启发。

问题就在这里:

for (Nodes child : nodePrintList) {             
    //...
    child.setX(parentNode.getX()+25);
    //...
}

程序代码始终将子节点的位置设置为与父节点的x和y固定距离,而不管它在哪个节点上。

一种解决方案:

for (int idx = 0; idx < nodePrintList.size(); idx++) {
    Nodes node = nodePrintList.get(idx);             
    //...
    child.setX(parentNode.getX()+ 25 * ((float)(nodePrintList.size()-1)/2 - idx);
    //...
}

虽然我的数学可能有一点偏差,但这应该将所有子节点平均放置在父节点的正下方,每一个节点距离下一个节点25个单位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM