2014-03-18 2 views
0

나는 이미 답변을 검색했습니다. 올바른 방향으로 절 지적 일부 주제는 다음과 같습니다동적으로 트리 그리기 문제

How to draw a tree representing a graph of connected nodes? http://www.daniweb.com/software-development/java/threads/151175/drawing-tree-with-jframe

어쨌든, 여기에 문제가 있습니다. 제 3 자의 물건을 사용하지 않고 JFrame에 트리를 그릴 수 있어야합니다. 그냥 스윙에서 사용할 수있는 방법. 내가 가지고있는 코드는 다음과 같습니다. Tree 클래스에는 포함되지 않았지만 텍스트 파일을 가져 와서 트리 구조로 파싱합니다. 나는 두 가지 문제를 겪고있다. 첫째, 노드의 타원형에 대한 가치를 얻을 수 없다. 값은 문자열로 저장되며 노드를 통과해야합니다. 둘째, paintComponent를 덮어 썼음에도 선이 나타나지 않습니다. 누군가 도울 수 있습니까?

NodeLabel :

public class NodeLabel extends JLabel{ 

public Node node; 
public Point topConnection; 
public Point bottomConnection; 

public NodeLabel(Node _node){ 
    super(_node.value); 
    node = _node; 

    this.setText(node.value); 
    this.add(new JLabel(node.value)); 
    topConnection = new Point(this.getWidth()/2, 0); 
    bottomConnection = new Point(this.getWidth()/2, this.getHeight()); 
} 


@Override 
public void paintComponent(Graphics g){ 
    g.drawOval(5, 5, 25, 15); 
} 

DRAWTREE 클래스 :

private ArrayList<NodeLabel> nodes; 
private Tree tree; 
private NodeLabel root; 
private int currentX; 
private int currentY; 

public DrawStuff(Tree _tree){ 
    tree = _tree; 
    currentX = 40; 
    currentY = 0; 
    this.setLayout(null); 
    this.setMinimumSize(new Dimension(300, 300)); 

    root = new NodeLabel(tree.root); 
    root.setHorizontalAlignment(SwingConstants.CENTER); 
    this.add(root); 
    root.setBounds(currentX, currentY, currentX + 20, currentY + 25); 
//  root.setLocation(currentX, currentY); 



    currentX = currentX - 20; 
    currentY = currentY + 30; 

    for(Node node : tree.root.children){ 
     NodeLabel temp = new NodeLabel(node); 
     this.add(temp); 
     temp.setBounds(currentX, currentY, currentX +20, currentY + 25); 
     this.add(drawEdge(this.getGraphics(), root, temp)); 

     temp.setLocation(currentX, currentY); 
     currentX += 40; 


     System.out.println("child added"); 
    } 

} 

private JPanel drawEdge(Graphics g, NodeLabel parent, NodeLabel child){  
    final Point p1 = parent.bottomConnection; 
    final Point p2 = child.topConnection; 

    JPanel line = new JPanel(){ 
     @Override 
     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 
      g.drawLine(p1.x, p1.y, p2.x, p2.y); 
     } 
    }; 

    return line; 
} 

public static void main(String[] args) throws Exception{ 
    Tree tree = new Tree(args[0]); 
    System.out.println(tree.toString()); 
    DrawStuff dTree = new DrawStuff(tree); 
    dTree.setVisible(true); 
} 

트리 클래스 : 트리 데이터 구조에서 잘 형성 파일 (거의 XML) 및 저장을합니다. 태그는 다음과 같이 구성됩니다. 중첩 태그가 계층을 표시합니다. IE :

공용 클래스 트리 {

Node root; 

/** 
* Tree constructor method 
* Takes the file and constructs a tree based on the contents 
* @param filename the name(or path) of the file to extract information from 
*/ 
//Take the file and create all the nodes 
public Tree(String filename) throws Exception{ 
    File file = new File(filename); 
    Scanner s = new Scanner(file); 

    Node current = new Node("x"); 
    if(s.hasNext()){ 
     s.next(); 
     String temp = s.next(); 
     String value = temp.substring(0, temp.length()-1); 
     root = new Node(value); 
     current = root; 
    } 
    while(s.hasNext()){ 
     String temp = s.next(); 
     if(temp.charAt(1) != '/'){ //then it is an open Tag. 
      temp = s.next(); //this is our value + ">" 
      String value = temp.substring(0, temp.length()-1); 
      //create a new node with the value that's the child of our current node 
      Node tempNode = current.addChild(value 
        ); 
      //current = the node we just created 
      current = tempNode;  
     } else{ 
      if (current.parent!= null){ 
      current = current.parent; 
      } 
     } 
    } 
} 

public String toString(){ 
    return root.toString(); 

} 


public class Node{ 

    Node parent; 
    ArrayList<Node> children; 
    String value; 

    public Node(String value){ 
     children = new ArrayList<Node>(); 
     this.value = value; 
    } 

    public Node(String value, Node parent){ 
     this.parent = parent; 
     children = new ArrayList<Node>(); 
     this.value = value; 
    } 

    public Node addChild(String value){ 
     Node temp = new Node(value, this); 
     this.children.add(temp); 
     return temp; 
    } 

    public String toString(){ 
     String result = ""; 
     result += this.value + "\n"; 

     for(Node child:children){ 
      result += " " + child.toString(); 
     } 
     return result; 
    } 

} 

}

내가 볼 수있는 심각한 문제의 숫자가 있습니다

답변

1

. 먼저 여러 구성 요소를 사용하여 이러한 방식으로 고유 한 요소를 렌더링하지 마십시오. 대신 전체 내용을 렌더링 할 수있는 단일 사용자 정의 구성 요소를 만듭니다. 당신이 Graphics 컨텍스트를 통과 할 수 있도록 이것은 NodeLabel 클래스에서 extends JLabel를 제거하여 당신이 이해하지 않는 것 컨텍스트를 좌표의 문제 ...

시작을 극복,이 클래스는 단순히 어떤 방식으로 drawable을해야한다 그것으로 그리고 그것은 스스로 칠할 것입니다.

JPanel과 같은 것으로부터 확장되는 TreePanel을 만듭니다. 이는 트리의 기본 컨테이너 역할을합니다. 트리 참조를 설정할 수있는 방법을 제공하십시오.

은 자세한 내용

+0

을위한 Performing Custom Painting2D Graphics에 대해 자세히 살펴 ... 당신이 맞는 볼 그들 사이의 선을 그릴 구성 요소의 paintComponent 메서드를 재정의하고 그것에 노드를 렌더링 난 당신이 방금 말한 모든 것을 이해 바랍니다 . 이것은 대략 ... 제 3의 시간, 나는 생각합니다 ... 나는 모든 스윙을 사용했습니다. 내 제한된 GUI 지식은 약간 다른 actionscript에서 비롯됩니다. 모든 것이 하나의 구성 요소가되어야한다고 생각했습니다./ 그래, TreePanel을 유일한 구성 요소로 만들 수 있습니다. 구성 요소가 아닌 경우 Panel에 NodeLabel과 같은 것을 어떻게 추가합니까? 또한 drawable 인터페이스 레이블을 구현해야합니까 또는 drawable 수 있도록 paintComponent 메서드를 재정의해야합니까? –

+0

'TreePanel'에 아무것도 추가하지 않고'Tree'에 대한 참조를 제공하고'paintComponent' 메서드를 사용하여 노드와 선을 적절하게 렌더링합니다. 'Tree' 구현을 제공 할 수 있다면 더 자세한 내용을 제공하는 것이 더 쉬울 수도 있습니다. – MadProgrammer

+0

OP에 트리 코드를 추가했습니다. –