0

ツリーのすべてのノードを JPanel に再帰的に描画しようとしています。

次のようになります。

ここに画像の説明を入力

ここでBCD、 は の子ですA

そして、EFの子です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新しい行ごとに1回インクリメントする方法を見つけることだと思います...そして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;
}
4

2 に答える 2

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
}

ただし、これは 1 つの問題にすぎません。もう 1 つの問題は、ノードを適切に配置するには、各ブランチの合計幅を考慮する必要があることです。これを修正する 1 つの方法は、各ブランチの幅の合計を返し、paintComponent(g, nodes)returnxを持ち、これ (およびオフセット) を次の子に使用することです。上記のコードは、次のようになります。

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)

これにはおそらくまだ多少の調整が必要ですが、アイデアが得られるはずです。

于 2013-06-19T18:17:32.270 に答える
2

問題はここにあります:

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

プログラム コードは、どのノードであるかに関係なく、常に子ノードの位置を親からの x および y の固定距離に設定しています。

これに対する1つの解決策:

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 ユニットずつ離れます。

于 2013-06-19T18:20:41.753 に答える