У меня есть рабочая программа, которая отображает визуальное представление бинарного дерева поиска.Я новичок в ООП и знаю, что классы / методы, которые рисуют дерево, можно улучшить.У меня проблемы с поиском лучшего способа.
Сейчас программа отображает дерево в виде значка в JFrame.В методе iconIcon paintIcon мы передаем параметры x и y методу getNodePaintInfo в классе BinarySearchTree.Метод «getNodePaintInfo» возвращает массив объектов «NodePaintInfo», которые указывают местоположение рисования каждого узла, текст метки и ребра.Мы используем эту информацию для построения и рисования «NodeIcon» (фактического визуального представления узла BST) и для рисования краев дерева.
Метод paintIcon treeDisplayIcon в DisplayFrame.java:
public void paintIcon(Component c, Graphics g, int x, int y)
{
BinarySearchTree binTree = dataSet.getData();
int nodeCount = binTree.getNodeCount();
int nodeSize = nodeCount > 0 ? FRAME_WIDTH / nodeCount : 0;
NodePaintInfo[] nodeArr = binTree.getNodePaintInfo(nodeSize, x, y);
Graphics2D g2 = (Graphics2D) g;
for (NodePaintInfo nodeInfo : nodeArr)
{
NodeIcon nodeIcon = new NodeIcon(nodeInfo.getLabel(), nodeSize);
Point paintPt = nodeInfo.getPaintLocation();
Line2D.Double leftChildEdge = nodeInfo.getLeftChildLine();
Line2D.Double rightChildEdge = nodeInfo.getRightChildLine();
if (leftChildEdge != null)
g2.draw(leftChildEdge);
if (rightChildEdge != null)
g2.draw(rightChildEdge);
nodeIcon.paintIcon(c, g2, (int) paintPt.getX(), (int) paintPt.getY());
}
}
getNodePaintInfo метод в BinarySearchTree.java
public NodePaintinfo[] getNodePaintInfo(int nodeSize, int x, int y)
{
ArrayList<NodePaintInfo> returnList = new ArrayList<NodePaintInfo>();
// Inorder traversal to get x positions
Node[] dfs = this.getInorder();
// Levelorder traversal to get y positions
Node[][] levelArr = this.getLevels();
// Map node's x location to its data
HashMap<String, Integer> xPosMap = new HashMap<String, Integer>();
for (int i = 0; i < dfs.length; i++)
xPosMap.put(dfs[i].data, new Integer(x + i * nodeSize));
for (int i = 0; i < levelArr.length; i++)
{
for (int j = 0; j < levelArr[i].length; j++)
{
Node currentNode = levelArr[i][j];
int xPos = xPosMap.get(currentNode.data);
int yPos = y + i * nodeSize;
Point paintDst = new Point(xPos, yPos);
int centerX = xPos + nodeSize / 2;
int centerY = yPos + nodeSize / 2;
Point midPoint = new Point(centerX, centerY);
Line2D.Double leftChild = null;
if (currentNode.left != null)
{
int leftCenterX = xPosMap.get(currentNode.left.data) + nodeSize / 2;
int leftCenterY = yPos + nodeSize + nodeSize / 2;
Point leftPoint = new Point(leftCenterX, leftCenterY);
// Line connecting currentNode's center to the center of its left child
leftChild = new Line2D.Double(midPoint, leftPoint);
}
Line2D.Double rightChild = null;
if (currentNode.right != null)
{
int rightCenterX = xPosMap.get(currentNode.right.data) + nodeSize / 2;
int leftCenterY = yPos + nodeSize + nodeSize / 2;
Point leftPoint = new Point(rightCenterX, rightCenterY);
// Line connecting currentNode's center to the center of its right child
rightChild = new Line2D.Double(midPoint, rightPoint);
}
returnList.add(new NodePaintInfo(levelArr[i][j].data, paintDat, leftChild, rightChild));
}
}
NodePaintInfo[] returnArr = new NodePaintInfo{returnList.size()];
returnArr = (NodePaintInfo[]) returnList.toArray(returnArr);
return returnArr;
}
Некоторые нарушения дизайна OO, которые сразу бросаются мне в глаза (Исправьте меня, если я ошибаюсь):
Класс BinarySearchTree не должен напрямую работать с координатами из JFrame.
Фактические фигуры, которые видит пользователь, в настоящее время разделены между двумя классами.Линии ребер находятся в «NodePaintInfo», а форма узла - в «NodeIcon».Все визуальные компоненты узла имеют больше смысла в одном классе.
Пожалуйста, дайте мне знать, как можно улучшить дизайн!