我正在使用Model–view–controller设计模式,我需要一个用于我的BST / AVL模型的UI查看器,我已经开发了模型和控制器逻辑,我只需要查看器,我这样做现在不需要处理图形,如果某人有一个 Viewer 类,其方法采用树的根并绘制它,不需要高级动画或效果,那将非常有用
类似
SimpleBSTreeViewer.draw(myTree.getRoot());
树的节点结构
public class NodeBST <T extends Comparable<T>> {
private T data;
private NodeBST<T> left;
private NodeBST<T> right;
private NodeBST<T> parent;
//other methods go here ...
}
这将有助于编写逻辑部分的重点,
我搜索过并找到了其他代表树的小程序,但它们在同一个类中有模型逻辑和视图,我在模型 - 视图 - 控制器模式(MVC模式)中工作,最好将模型与视图分开尽可能地,我只想要一个观众用于我的模型
注意:这是我需要的样本(我已经使用了JTree,但这并不令人满意。)
答案 0 :(得分:2)
获取Jgraphx库并从HelloWorld
开始
我编写此类的例子
使用this问题计算节点的坐标。
package algorithms.searching.bst;
import java.util.Random;
import javax.swing.JFrame;
import log.Logger;
import algorithms.searching.bst.avl.AVL;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.view.mxGraph;
@SuppressWarnings("serial")
public class TreeViewer<T extends Comparable<T>> extends JFrame {
static private int CANVAS_HEIGHT = 600;
static private int CANVAS_WIDTH = 1000;
private int rootY = 10;
private int NODE_SIZE = 25;
private int ROW_HEIGHT = 50;
mxGraph graph = new mxGraph();
Object parent = graph.getDefaultParent();
/**
* draws a tree starting from this root
*
* @param root
* @param depth
* number of nodes to the root (including root)
* @param index
* index of node in this level (leftChildIndex = parentIndex * 2
* - 1) and (rightChildIndex = parentIndex * 2)
* @return
*/
public Object drawTree(NodeBST<T> root, int depth, int index) {
if (root == null) {
return null;
}
// draw root
/*
* leftChildIndex = parentIndex * 2 - 1
* rightChildIndex = parentIndex *2
*
*
* x = index * canvasWidth / (2^depth + 1)
*
* y = depth * canvasHeight / treeDepth
*/
int myX = (int) ((CANVAS_WIDTH * (index)) / (Math.pow(2, depth - 1) + 1));
Object rootVertex = graph.insertVertex(parent, null, root.getData(),
myX, depth * ROW_HEIGHT + rootY, NODE_SIZE, NODE_SIZE);
Logger.log("new x coordinate=" + myX);
// recurse for right child
Object rightChildVertex = drawTree(root.getRight(), depth + 1,
index * 2);
if (rightChildVertex != null) {// edge
graph.insertEdge(parent, null, "R", rootVertex, rightChildVertex,
"startArrow=none;endArrow=none;strokeWidth=1;strokeColor=green");
}
Object leftChildVertex = drawTree(root.getLeft(), depth + 1,
index * 2 - 1);
// recurse for right child
if (leftChildVertex != null) { // edge
graph.insertEdge(parent, null, "L", rootVertex, leftChildVertex,
"startArrow=none;endArrow=none;strokeWidth=1;strokeColor=green");
}
return rootVertex;
}
/**
* Redraw the whole tree
*
* @param root
* the root of tree to be drawn
*/
public void update(NodeBST<T> root) {
graph.getModel().beginUpdate();
try {
Object[] cells = graph.getChildCells(parent, true, false);
graph.removeCells(cells, true);
drawTree(root, 1, 1);
} finally {
graph.getModel().endUpdate();
}
}
public TreeViewer(NodeBST<T> root) {
// super("Hello, World!");
this.update(root);
mxGraphComponent graphComponent = new mxGraphComponent(graph);
getContentPane().add(graphComponent);
}
public static void main(String[] args) {
AVL<Integer> bst = new AVL<Integer>();//use AVL tree class
Random randomGenerator = new Random();
for (int i = 0; i < 20; i++) {//try generating 20 random integers
bst.insert(randomGenerator.nextInt(1000));
}
TreeViewer<Integer> myTreeViewer=new TreeViewer<Integer>(bst.getRoot());
JFrame frame = myTreeViewer;
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
frame.setVisible(true);
}
}
只需修改此类即可获取树类