Java中描述二叉树遍历的图

Java中描述二叉树遍历的图,java,graph,paintcomponent,tree-traversal,Java,Graph,Paintcomponent,Tree Traversal,在我的程序中,我使用一个名为“curNode”的变量来表示树根。每次我在文本字段中输入0或1时,curNode将变为curNode.left或curNode.right,然后新的当前节点将变为红色而不是黑色。但它只有在我输入了一些东西之后才能工作,在init中,树根没有红色。 这是我的TriesView.java: package tree; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.K

在我的程序中,我使用一个名为“curNode”的变量来表示树根。每次我在文本字段中输入0或1时,curNode将变为curNode.left或curNode.right,然后新的当前节点将变为红色而不是黑色。但它只有在我输入了一些东西之后才能工作,在init中,树根没有红色。 这是我的TriesView.java:

package tree;

import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Stack;

import javax.swing.*;

public class TriesView extends JPanel {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private Huffman tree; // A binary tree to be displayed
    private PaintTree paintTree;
    private JTextField pathTxt;
    public HuffmanNode curNode;
    private Stack<String> txtStack = new Stack<String>();

    /** Construct a view for a binary tree */
    public TriesView(Huffman tree) {   
        this.tree = tree; // Set a binary tree to be displayed
        curNode = tree.root;
        paintTree = new PaintTree();
        setUI();
    }

    /** Initialize UI for binary tree */
    private void setUI() {
        this.setLayout(new BorderLayout()); 
        JScrollPane scrollPane = new JScrollPane(paintTree, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        add(scrollPane, BorderLayout.CENTER);

        if(!tree.isEmpty()){
            paintTree.setPreferredSize(new Dimension((int)Math.pow(2, (tree.getDepth() + 1)) * paintTree.radius, (tree.getDepth() + 1) * paintTree.vGap + paintTree.radius));
            scrollPane.setPreferredSize(new Dimension((int)Math.pow(2, (tree.getDepth() + 1)) * paintTree.radius, (tree.getDepth() + 1) * paintTree.vGap + paintTree.radius));
        }
        JPanel panel = new JPanel();
        pathTxt = new JTextField(10);
        panel.add(new JLabel("Enter key path: "));
        panel.add(pathTxt);
        add(panel, BorderLayout.SOUTH);

        pathTxt.addKeyListener(new KeyAdapter() {
            public void keyPressed(KeyEvent evt) {
                String txt = pathTxt.getText();
                txtStack.push(txt);
            }
            public void keyReleased(KeyEvent evt) {
                String txt = pathTxt.getText();
                String oldTxt = pathTxt.getText();
                if(!txtStack.isEmpty())
                    oldTxt = txtStack.pop();
                if (txt.matches("^[01]*$") != true) {
                    pathTxt.setText(oldTxt);
                    JOptionPane.showMessageDialog(null, "Ký tự không hợp lệ");
                    return;
                }
                HuffmanNode temp = tree.root;
                for(int i = 0; i < txt.length() && temp != null; i++){
                    if(txt.charAt(i) == '0'){
                        temp = temp.left;
                    }else if(txt.charAt(i) == '1'){
                        temp = temp.right;
                    }
                }
                if(temp == null){
                    JOptionPane.showMessageDialog(null, "Dãy không hợp lệ");
                    pathTxt.setText(oldTxt);
                    return;
                }
                curNode = temp;
                scrollPane.repaint();
            }
        });
    }

    // Inner class PaintTree for displaying a tree on a panel
    class PaintTree extends JPanel {
        /**
         * 
         */
        private static final long serialVersionUID = 1L;
        private int radius = 20; // Tree node radius
        private int vGap = 50; // Gap between two levels in a tree

        protected void paintComponent(Graphics g) {
            super.paintComponent(g);

            if (tree != null) {
                // Display tree recursively    
                //              displayTree(g, tree.root, (int)Math.pow(2, tree.root.height - 1)*radius, 30, (int)Math.pow(2, tree.root.height-2)*radius); 
                displayTree(g, tree.root, getWidth()/2, 30, getWidth()/4); 
            }
        }

        /** Display a subtree rooted at position (x, y) */
        private void displayTree(Graphics g, HuffmanNode root, 
                int x, int y, int hGap) {
            // Display the root
            if(root == null) return;
            Graphics2D ga = (Graphics2D)g;
            if(curNode == root){
                ga.setPaint(Color.RED);
            }else{
                ga.setPaint(Color.BLACK);
            }
            ga.fillOval(x - radius, y - radius, 2 * radius, 2 * radius);
            ga.setPaint(Color.BLACK);
            ga.setColor(Color.WHITE);
            ga.drawString(String.valueOf(root.frequency), x - 6, y + 4);
            ga.setColor(Color.RED);
            ga.drawString(String.valueOf(root.value), x - 6, y + 36);
            ga.setColor(Color.BLACK);

            if (root.left != null) {
                // Draw a line to the left node
                connectLeftChild(g, x - hGap, y + vGap, x, y);
                ga.drawString("0", x - hGap/2 - 12, y + vGap/2);
                displayTree(g, root.left, x - hGap, y + vGap, Math.max(hGap / 2, radius));
            }

            if (root.right != null) {
                // Draw a line to the right node
                connectRightChild(g, x + hGap, y + vGap, x, y);
                ga.drawString("1", x + hGap/2 + 5, y + vGap/2);
                // Draw the right subtree recursively
                displayTree(g, root.right, x + hGap, y + vGap, Math.max(hGap / 2, radius));  
            }
        }

        public int getRadius(){
            return this.radius;
        }

        public int getVGap(){
            return this.vGap;
        }

        /** Connect a parent at (x2, y2) with 
         * its left child at (x1, y1) */
        private void connectLeftChild(Graphics g, 
                int x1, int y1, int x2, int y2) { 
            double d = Math.sqrt(vGap * vGap + (x2 - x1) * (x2 - x1));
            int x11 = (int)(x1 + radius * (x2 - x1) / d);
            int y11 = (int)(y1 - radius * vGap / d);
            int x21 = (int)(x2 - radius * (x2 - x1) / d);
            int y21 = (int)(y2 + radius * vGap / d);
            g.drawLine(x11, y11, x21, y21);
        }

        /** Connect a parent at (x2, y2) with 
         * its right child at (x1, y1) */
        private void connectRightChild(Graphics g, 
                int x1, int y1, int x2, int y2) {
            double d = Math.sqrt(vGap * vGap + (x2 - x1) * (x2 - x1));
            int x11 = (int)(x1 - radius * (x1 - x2) / d);
            int y11 = (int)(y1 - radius * vGap / d);
            int x21 = (int)(x2 + radius * (x1 - x2) / d);
            int y21 = (int)(y2 + radius * vGap / d);
            g.drawLine(x11, y11, x21, y21);
        }
    }
}
包树;
导入java.awt.*;
导入java.awt.event.KeyAdapter;
导入java.awt.event.KeyEvent;
导入java.util.Stack;
导入javax.swing.*;
公共类TriesView扩展了JPanel{
/**
* 
*/
私有静态最终长serialVersionUID=1L;
私有哈夫曼树;//要显示的二叉树
私人漆树漆树;
私有jtextfieldpathtxt;
公共赫夫曼节点;
私有堆栈txtStack=新堆栈();
/**构造二叉树的视图*/
公共特里斯维尤(哈夫曼树){
this.tree=tree;//设置要显示的二叉树
curNode=tree.root;
paintTree=新的paintTree();
setUI();
}
/**初始化二叉树的用户界面*/
私有void setUI(){
此.setLayout(新的BorderLayout());
JScrollPane scrollPane=新的JScrollPane(画树、ScrollPaneConstants.VERTICAL滚动条、ScrollPaneConstants.HORIZONTAL滚动条);
添加(滚动窗格,BorderLayout.CENTER);
如果(!tree.isEmpty()){
paintTree.setPreferredSize(新维度((int)Math.pow(2,(tree.getDepth()+1))*paintTree.radius,(tree.getDepth()+1)*paintTree.vGap+paintTree.radius);
scrollPane.setPreferredSize(新维度((int)Math.pow(2,(tree.getDepth()+1))*paintTree.radius,(tree.getDepth()+1)*paintTree.vGap+paintTree.radius);
}
JPanel面板=新的JPanel();
pathTxt=新的JTextField(10);
添加(新JLabel(“输入键路径”);
panel.add(pathTxt);
添加(面板,边界布局。南部);
addKeyListener(新的KeyAdapter(){
按下公共无效键(KeyEvent evt){
String txt=pathTxt.getText();
txtStack.push(txt);
}
公共无效密钥已释放(密钥事件evt){
String txt=pathTxt.getText();
字符串oldTxt=pathTxt.getText();
如果(!txtStack.isEmpty())
oldTxt=txtStack.pop();
如果(txt.matches(“^[01]*$”)=true){
setText(oldTxt);
showMessageDialog(null,“Kýtự Khong hợPLệ");
返回;
}
HuffmanNode temp=tree.root;
对于(int i=0;i