Объектно-ориентированный дизайн - рисование BST с использованием Swing - PullRequest
0 голосов
/ 24 января 2019

У меня есть рабочая программа, которая отображает визуальное представление бинарного дерева поиска.Я новичок в ООП и знаю, что классы / методы, которые рисуют дерево, можно улучшить.У меня проблемы с поиском лучшего способа.

Сейчас программа отображает дерево в виде значка в 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, которые сразу бросаются мне в глаза (Исправьте меня, если я ошибаюсь):

  1. Класс BinarySearchTree не должен напрямую работать с координатами из JFrame.

  2. Фактические фигуры, которые видит пользователь, в настоящее время разделены между двумя классами.Линии ребер находятся в «NodePaintInfo», а форма узла - в «NodeIcon».Все визуальные компоненты узла имеют больше смысла в одном классе.

Пожалуйста, дайте мне знать, как можно улучшить дизайн!

...