对于具有层次关系的结构,使用树控件描述是非常方便的,如文件夹及其子文件夹之间的关系、国家的行政结构关系等。本实例将使用树控件来表示中国的各个行政区域。使用Swing库中定义的工具类可以非常容易地实现。实例运行效果如图

14.25.png

说明:单击三角形的小图标可以显示和隐藏树节点。

DefaultMutableTreeNode是树数据结构中的通用节点。一个树节点最多可以有一个父节点、0 或多个子节点。DefaultMutableTreeNode 为检查和修改节点的父节点和子节点提供操作,也为检查节点所属的树提供操作。节点的树是所有节点的集合,通过从某一节点开始并沿着父节点和子节点的所有可能的链接,可以访问这些节点。可以使用其含有参数的构造方法在创建节点对象时定义节点的内容,该方法的声明如下:

public DefaultMutableTreeNode(Object userObject)

参数说明

userObject:用户提供的 Object,它构成节点的数据。

提示参数userObject的类型是Object,这意味着可以使用File等类型作为树的节点。

使用add()方法为一个节点增加子节点就可以实现层次关系,该方法的声明如下:

public void add(MutableTreeNode newChild)

参数说明

newChild:作为此节点的子节点添加的节点。

1)编写类ChinaGeographyTree,该类继承了JFrame。在框架中包含了一棵树,在树中显示了中国的直辖市、省、自治区和特别行政区信息。

2)编写方法do_this_windowActivated(),用来监听窗体激活事件。在该方法中,为树控件增加节点信息。核心代码如下:

package com.mingrisoft.jtree;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.UIManager;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import java.awt.Font;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

public class ChinaGeographyTree extends JFrame {
    
    /**
     * 
     */
    private static final long serialVersionUID = -6221329006071145576L;
    private JPanel contentPane;
    private JTree tree;
    
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
        } catch (Throwable e) {
            e.printStackTrace();
        }
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    ChinaGeographyTree frame = new ChinaGeographyTree();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    
    /**
     * Create the frame.
     */
    public ChinaGeographyTree() {
        addWindowListener(new WindowAdapter() {
            @Override
            public void windowActivated(WindowEvent e) {
                do_this_windowActivated(e);
            }
        });
        setTitle("\u4E2D\u56FD\u884C\u653F\u533A\u57DF\u6811");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);
        
        JScrollPane scrollPane = new JScrollPane();
        contentPane.add(scrollPane, BorderLayout.CENTER);
        
        tree = new JTree();
        tree.setFont(new Font("微软雅黑", Font.PLAIN, 16));
        scrollPane.setViewportView(tree);
    }
    
    protected void do_this_windowActivated(WindowEvent e) {
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
        DefaultMutableTreeNode municipalities = new DefaultMutableTreeNode("直辖市");
        municipalities.add(new DefaultMutableTreeNode("北京"));
        municipalities.add(new DefaultMutableTreeNode("上海"));
        municipalities.add(new DefaultMutableTreeNode("天津"));
        municipalities.add(new DefaultMutableTreeNode("重庆"));
        DefaultMutableTreeNode province = new DefaultMutableTreeNode("省");
        province.add(new DefaultMutableTreeNode("黑龙江"));
        province.add(new DefaultMutableTreeNode("吉林"));
        province.add(new DefaultMutableTreeNode("辽宁"));
        province.add(new DefaultMutableTreeNode("江苏"));
        province.add(new DefaultMutableTreeNode("安徽"));
        province.add(new DefaultMutableTreeNode("四川"));
        province.add(new DefaultMutableTreeNode("青海"));
        province.add(new DefaultMutableTreeNode("山东"));
        province.add(new DefaultMutableTreeNode("广东"));
        province.add(new DefaultMutableTreeNode("河南"));
        province.add(new DefaultMutableTreeNode("湖南"));
        province.add(new DefaultMutableTreeNode("海南"));
        province.add(new DefaultMutableTreeNode("江西"));
        province.add(new DefaultMutableTreeNode("山西"));
        province.add(new DefaultMutableTreeNode("陕西"));
        province.add(new DefaultMutableTreeNode("河北"));
        province.add(new DefaultMutableTreeNode("湖北"));
        province.add(new DefaultMutableTreeNode("贵州"));
        province.add(new DefaultMutableTreeNode("浙江"));
        province.add(new DefaultMutableTreeNode("福建"));
        province.add(new DefaultMutableTreeNode("台湾"));
        province.add(new DefaultMutableTreeNode("甘肃"));
        province.add(new DefaultMutableTreeNode("云南"));
        DefaultMutableTreeNode ARegion = new DefaultMutableTreeNode("自治区");
        ARegion.add(new DefaultMutableTreeNode("内蒙古自治区"));
        ARegion.add(new DefaultMutableTreeNode("宁夏回族自治区"));
        ARegion.add(new DefaultMutableTreeNode("新疆维吾尔族自治区"));
        ARegion.add(new DefaultMutableTreeNode("西藏自治区"));
        ARegion.add(new DefaultMutableTreeNode("广西壮族自治区"));
        DefaultMutableTreeNode SARegion = new DefaultMutableTreeNode("特别行政区");
        SARegion.add(new DefaultMutableTreeNode("香港"));
        SARegion.add(new DefaultMutableTreeNode("澳门"));
        root.add(municipalities);
        root.add(province);
        root.add(ARegion);
        root.add(SARegion);
        DefaultTreeModel model = new DefaultTreeModel(root);
        tree.setModel(model);
    }
}

心法领悟:树结构简介。

一棵树由若干节点组成,每个节点有两种状态:没有子节点的称为叶子节点,具有子节点的称为父节点。除了根节点外,每个节点都有唯一的父节点。一棵树只有一个根节点。由若干树组成的集合称为森林。关于树的更加详细的介绍请参考专门的数据结构教材。