我已经找到了答案。一些指向正确方向的主题是:
How to draw a tree representing a graph of connected nodes? http://www.daniweb.com/software-development/java/threads/151175/drawing-tree-with-jframe
无论如何,这是问题所在。我需要能够使用没有第三方的东西将树绘制到JFrame中;只是摆动的方法。我的代码如下:我没有包含的Tree类,但它需要一个文本文件并将其解析为树结构。我遇到了两个问题:首先,我无法获得节点的值以显示在椭圆形中。该值存储为字符串,应该通过Node传递。其次,即使我覆盖了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:
public class Tree {
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;
}
}
}
答案 0 :(得分:1)
我可以看到一些严重的问题。首先,不要使用多个组件以这种方式呈现不同的元素。而是创建一个能够呈现整个内容的自定义组件。这克服了你似乎不理解的坐标上下文问题......
首先从extends JLabel
课程中移除NodeLabel
,此类应该以某种方式drawable
,以便您可以将Graphics
上下文传递给它它会画自己。
创建一个TreePanel
,其范围从JPanel
开始。这将充当树的主要容器。提供一种可以设置树引用的方法。覆盖组件的paintComponent
方法并将节点渲染到它,在你认为合适的情况下在它们之间绘制线条......