我正在尝试以递归方式将树的所有节点绘制到JPanel上。
它应该是这样的:
其中B
,C
,D
是A
的孩子。
并且E
,F
是B
父子关系的输出是准确的:
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
位置与其他孩子的位置重叠......所以每个孩子只显示1个子节点:
我认为我要做的是找到一种方法,每个新的孩子行增加一次y
...并为父母的每个孩子增加x
,这样他们就能很好地放在一个孩子身上row ...但节点的坐标正在重置。
有什么想法吗?
代码:
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;
}
答案 0 :(得分:2)
主要问题似乎出现在for
方法的paintComponent
循环中。在这里,您为每个孩子使用相同的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)
这可能仍需要一些修补,但它应该给你一个想法。
答案 1 :(得分:2)
问题就在这里:
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个单位。