swing_树_JTree概述

news2024/12/24 3:18:25

JTree、TreeModel实现树

树也是图形用户界面中使用非常广泛的GUI组件,在Windows资源管理器中,将我们所看到的目录称为树:

计算机世界里的树是由一系列具有严格父子关系的结点组成的,每个结点既可以是上一级结点的子结点,也可以是其下一级结点的父结点,因此同一个结点既可以是父结点也可以是子结点。

按照结点是否包含子结点,可以把结点分为下面两类:

        普通结点:包含子结点的结点;

        叶子结点:没有子结点的结点;

按照结点是否具有唯一的父结点,可以把结点分为下面两类:

        根结点:没有父结点的结点,计算机中,一棵树只能有一个根结点

        普通结点:具有唯一父结点的结点

创建树:

package com.aynu.layout;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;

public class SimpleJTree {

    JFrame jf = new JFrame("简单树");


    public void init() {

        //创建DefaultMutableTreeNode对象来代表结点
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
        DefaultMutableTreeNode henan = new DefaultMutableTreeNode("河南");
        DefaultMutableTreeNode zhengzhou = new DefaultMutableTreeNode("郑州");
        DefaultMutableTreeNode luoyang = new DefaultMutableTreeNode("洛阳");
        DefaultMutableTreeNode shanxi = new DefaultMutableTreeNode("陕西");
        DefaultMutableTreeNode xian = new DefaultMutableTreeNode("西安");
        DefaultMutableTreeNode baoji = new DefaultMutableTreeNode("宝鸡");
        //组装结点之间的关系
        root.add(henan);
        root.add(shanxi);

        henan.add(zhengzhou);
        henan.add(luoyang);

        shanxi.add(xian);
        shanxi.add(baoji);

        //创建JTree对象
        JTree tree = new JTree(root);
        //把JTree放到窗口中展示
            jf.add(tree);

        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }


    public static void main(String[] args) {
        new SimpleJTree().init();
    }
}

JTree的其他外观设置方法:

tree.putClientProperty("JTree.lineStyle","None"):设置结点之间没有连接线

tree.putClientProperty("JTree.lineStyle","Horizontal"):设置结点之间只要水平分割线

package com.aynu.layout;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;

public class SimpleJTree {

    JFrame jf = new JFrame("简单树");


    public void init() {

        //创建DefaultMutableTreeNode对象来代表结点
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
        DefaultMutableTreeNode henan = new DefaultMutableTreeNode("河南");
        DefaultMutableTreeNode zhengzhou = new DefaultMutableTreeNode("郑州");
        DefaultMutableTreeNode luoyang = new DefaultMutableTreeNode("洛阳");
        DefaultMutableTreeNode shanxi = new DefaultMutableTreeNode("陕西");
        DefaultMutableTreeNode xian = new DefaultMutableTreeNode("西安");
        DefaultMutableTreeNode baoji = new DefaultMutableTreeNode("宝鸡");
        //组装结点之间的关系
        root.add(henan);
        root.add(shanxi);

        henan.add(zhengzhou);
        henan.add(luoyang);

        shanxi.add(xian);
        shanxi.add(baoji);

        //创建JTree对象
        JTree tree = new JTree(root);

        //tree.putClientProperty("JTree.lineStyle","None"):设置结点之间没有连接线
       // tree.putClientProperty("JTree.lineStyle","None");
        //tree.putClientProperty("JTree.lineStyle","Horizontal"):设置结点之间只要水平分割线
       // tree.putClientProperty("JTree.lineStyle","Horizontal");

        //把JTree放到窗口中展示
            jf.add(tree);

        //DefaultMutbleTreeNode getNextSibling:返回此结点的下一个兄弟结点
        DefaultMutableTreeNode nextNode = henan.getNextSibling();
        System.out.println(nextNode);
        //TreeNode getParent():返回此结点的父结点。如果此结点没有父结点则返回null
        TreeNode parent = henan.getParent();
        System.out.println(parent);
        //boolean isLeaf():返回该结点是否是叶子结点
        System.out.println(shanxi.isLeaf());
        System.out.println(xian.isLeaf());
        //boolean isRoot():返回当前结点是否是根结点
        System.out.println(shanxi.isRoot());
        System.out.println(root.isRoot());


        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }


    public static void main(String[] args) {
        new SimpleJTree().init();
    }
}


编辑树结点:

package com.aynu.layout;

import com.sun.source.tree.Tree;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.tree.*;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class SimpleJTree2 {

    JFrame jf = new JFrame("可编辑结点的树");

    //创建DefaultMutableTreeNode对象来代表结点
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("中国");
    DefaultMutableTreeNode henan = new DefaultMutableTreeNode("河南");
    DefaultMutableTreeNode zhengzhou = new DefaultMutableTreeNode("郑州");
    DefaultMutableTreeNode luoyang = new DefaultMutableTreeNode("洛阳");
    DefaultMutableTreeNode shanxi = new DefaultMutableTreeNode("陕西");
    DefaultMutableTreeNode xian = new DefaultMutableTreeNode("西安");
    DefaultMutableTreeNode baoji = new DefaultMutableTreeNode("宝鸡");

    //定义按钮,完成操作
    JButton addSiblingBtn = new JButton("添加兄弟结点");
    JButton addChildBtn = new JButton("添加子结点");
    JButton deleteBtn = new JButton("删除结点");
    JButton editBtn = new JButton("编辑当前结点");

    public void init() {

        //组装结点之间的关系
        root.add(henan);
        root.add(shanxi);

        henan.add(zhengzhou);
        henan.add(luoyang);

        shanxi.add(xian);
        shanxi.add(baoji);

        //创建JTree对象
        JTree tree = new JTree(root);

        //完成树的结点编辑的代码
        tree.setEditable(true);
        DefaultTreeModel model = (DefaultTreeModel) tree.getModel();

        //处理添加按钮
        addSiblingBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //添加兄弟结点逻辑

                //1.获取当前选中的结点
                DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                if (selectNode == null) {
                    return;
                }
                //2.获取当前结点的父结点
                DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode) selectNode.getParent();
                if (parentNode == null) {
                    return;
                }
                //3.创建新结点
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");

                //4.把新结点通过父结点进行添加
                int index = parentNode.getIndex(selectNode);
                model.insertNodeInto(newNode,parentNode,index);
                //5.显示新结点
                TreeNode[] pathToRoot = model.getPathToRoot(newNode);
                TreePath treePath = new TreePath(pathToRoot);
                tree.scrollPathToVisible(treePath);

                //6.重绘tree
                tree.updateUI();

            }
        });

        //添加子结点
        addChildBtn.addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                //为选中结点添加子结点

                //获取选中结点
                DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                if (selectNode==null){
                    return;
                }
                //创建新结点
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode("新结点");

                //把新结点添加到当前结点中
                selectNode.add(newNode);

                //显示新结点
                TreeNode[] pathToRoot = model.getPathToRoot(newNode);
                TreePath treePath = new TreePath(pathToRoot);
                tree.scrollPathToVisible(treePath);

                //重绘UI
                tree.updateUI();
            }
        });

        //删除处理
        deleteBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取选中结点
                DefaultMutableTreeNode selectNode = (DefaultMutableTreeNode) tree.getLastSelectedPathComponent();
                if (selectNode!=null && selectNode.getParent()!=null){
                    model.removeNodeFromParent(selectNode);
                }

            }
        });

        //处理编辑
        editBtn.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //获取当前选中结点的路径
                TreePath selectionPath = tree.getSelectionPath();
                //判断如果路径不为空,则设置该路径的最后一个结点可编辑
                if (selectionPath!=null){
                    tree.startEditingAtPath(selectionPath);
                }

            }
        });

        //组装视图
        jf.add(new JScrollPane(tree));

        JPanel jPanel =new JPanel();
        jPanel.add(addSiblingBtn);
        jPanel.add(addChildBtn);
        jPanel.add(deleteBtn);
        jPanel.add(editBtn);

        jf.add(jPanel, BorderLayout.SOUTH);


        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jf.pack();
        jf.setVisible(true);
    }


    public static void main(String[] args) {
        new SimpleJTree2().init();
    }
}


监听结点事件 :


使用DefaultTreeCellRenderer改变结点外观:


结点外观改变_扩展DefaultTreeCellRenderer:

实现TreeCellRenderer接口改变结点外观:

这种改变结点外观的方式是最灵活的,程序实现TreeCellRenderer接口时同样需要实现getTreeCellRendererComponent()方法,该方法可以返回任意类型的组件,该组件将作为Tree的结点,通过这种方法可以最大程度的改变结点的外观。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/531456.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【HMS Core】Health Kit如何获取跑步锻炼记录的轨迹记录?

【问题描述】 使用接口,"/healthkit/v1/activityRecords",可以正常获取跑步记录,但是里面没有附带轨迹数据,应该怎么获取每条记录的轨迹记录数据呢? 【解决方案】 1、获取锻炼记录的轨迹记录需要关联GPS详…

创业像是驾驶轮船,我们唯一可以做的就是掌好舵

一直拥有领先的认知是很难的,我们唯一可以做的是保持开放的心态,并主动获取新信息,从而不断地促进认知升级。 三年前,神策数据公众号曾发文《桑文锋:创业这五年》,传递了创始人 & CEO 桑文锋对创业的观…

【FMC136】AD9467之4通道 250MSPS 采样率16位AD 采集子卡模块得设计原理图中文资料

板卡概述 FMC136 是一款4 通道250MHz 采样率16 位AD 采集FMC子卡,符合VITA57 规范,可以作为一个理想的IO 模块耦合至FPGA前端,4 通道AD 通过高带宽的FMC 连接器(HPC)连接至FPGA 从 而大大降低了系统信号延迟。该板卡支…

Golang中函数的使用

目录 函数 函数特点 函数的使用 函数定义 函数的参数 函数的返回值 函数的变量作用域 函数的递归调用 函数的可变参数 函数的闭包 函数的 defer 语句 注意 函数 函数调用:函数调用时需要传递函数定义中要求的参数,并根据需要接收返回值。 …

专享策略05 | MACD波段套利交易策略

量化策略开发,高质量社群,交易思路分享等相关内容 大家好,2023俱乐部有4个专享,6个通用。其中专享是2个套利,1个盘口,1个CTA。本期是专享05策略,本年度第二个套利策略。 01、策略介绍 策略以MA…

CH32V3xx RT-Thread Nano调试记录

目录 1、工程创建2、代码修改与调试2.1 RT-Thread 配置2.2 打印串口修改2.3 测试验证1、工程创建 使用MounRiver集成开发环境可以直接创建带有RT-Thread Nano的工程,步骤如下: 打开MounRiver,点击新建MounRiver工程; 在模板类型处选择RT-Thread,然后选择使用的芯片型号,…

UNeXt:基于MLP的快速医学图像分割网络

文章目录 UNeXt: MLP-Based Rapid Medical Image Segmentation Network摘要本文方法Shifted MLPTokenized MLP Stage 实验结果 UNeXt: MLP-Based Rapid Medical Image Segmentation Network 摘要 UNeXt:一种基于卷积多层感知器(MLP)的图像分…

【 WebSocket 框架 】

文章目录 一、背景介绍二、原理解析三、代码示例四、效果验证 一、背景介绍 WebSocket 是从 HTML5 开始支持的一种网页端和服务端保持长连接的 消息推送机制 理解消息推送: 传统的 web 程序, 都是属于 “一问一答” 的形式. 客户端给服务器发送了一个 HTTP 请求, 服务器给客户…

数据类型、python数字、数据类型转换、字符串

1、python的数据类型 可以使用type&#xff08;&#xff09;函数获取任何对象的数据类型 x 10 print(type(x)) # 打印<class int> 2、python 数字 Int 或整数是完整的数字&#xff0c;正数或负数&#xff0c;没有小数&#xff0c;长度不限。 浮动或“浮点数”是…

JavaScript全解析——express

express 的基本使用 ●express 是什么? ○是一个 node 的第三方开发框架 ■把启动服务器包括操作的一系列内容进行的完整的封装 ■在使用之前, 需要下载第三方 ■指令: npm install express 1.基本搭建 // 0. 下载: npm install express// 0. 导入 const express express()…

DNF命令介绍

DNF命令介绍 DNF是新一代的rpm软件包管理器。他首先出现在 Fedora 18 这个发行版中。而最近&#xff0c;它取代了yum&#xff0c;正式成为 Fedora 22 的包管理器。 1. 安装DNF包管理器 yum -y install dnf2. 命令介绍

MQTT 5协议中的基础更改(二)

上期文章中给大家介绍了MQTT规范版本5中基础更改的信息和CONNACK返回码&#xff0c;本篇文章我们继续介绍MQTT5协议中的基础更改中其他新功能的细节描述。 01 干净启动 MQTT 3.1.1的其中一个主流功能是MQTT客户端使用清除会话&#xff08;cleanSession&#xff09;&#xff0…

promise缓存与缓存思想的总结

promise缓存与缓存思想的总结 JS单例模式关于promise缓存 JS单例模式 单例模式&#xff0c;保证一个类有且仅有一个实例&#xff0c;并提供一个访问它的全局访问点 我们举个简单的例子 class SingletonFLX {constructor(name, age) {this.name name;this.age age;}//静态方法…

港联证券投资前瞻:碳酸锂价格持续反弹 银行板块步入可积极配置阶段

昨日&#xff0c;两市股指全线反弹走高&#xff0c;沪指涨超1%收复3300点&#xff1b;创业板指午后涨超2%&#xff1b;截至收盘&#xff0c;沪指涨1.17%报3310.74点&#xff0c;深成指涨1.57%报11178.62点&#xff0c;创业板指涨2.11%报2299.93点&#xff0c;上证50指数涨1.75%…

【案例教程】Biome-BGC生态系统模型与Python融合技术应用

Biome-BGC是利用站点描述数据、气象数据和植被生理生态参数&#xff0c;模拟日尺度碳、水和氮通量的有效模型&#xff0c;其研究的空间尺度可以从点尺度扩展到陆地生态系统。 在Biome-BGC模型中&#xff0c;对于碳的生物量积累&#xff0c;采用光合酶促反应机理模型计算出每天…

无缝接入最新版NewBing

无缝接入最新版NewBing 1、NewBing 的接入网址 : 必应(bing.com) 2、接入方法: (1)必须使用 Microsoft Edge 浏览器 (2)注册一个自己的账号&#xff0c;注册步骤参考如下您可以通过以下步骤注册 Microsoft 账户 1.访问Microsoft的注册帐户页面 2.点击”创建账户”按钮。 3…

刷题65:不同的二叉搜索树

题意描述&#xff1a; 给你一个整数 n &#xff0c;求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种&#xff1f;返回满足题意的二叉搜索树的种数。 思路&#xff1a; 1、确定dp数组&#xff08;dp table&#xff09;以及下标的含义dp[i] &#xff1a;…

OA系统功能测试分析和学习教程(超详细)

OA系统可以简单快速地建立企业级的办公自动化系统。 办公自动化系统是员工及管理者使用频率最高的应用系统&#xff0c;可以极大提高公司的办公效率&#xff0c;帮助企业节省数字化、信息化办公的成本。本文中的OA系统来自于下面的资源&#xff1a; 包含诸多系统各功能模块&…

个人黄金投资要注意什么?如何降低黄金投资交易风险

黄金保值性强&#xff0c;自带避免功能&#xff0c;因此在投资者的理财组合中总能看到它的身影。但不可否认的是&#xff0c;黄金投资交易风险仍然存在。投资者在入场前应该多方了解&#xff0c;减小风险的危害。 黄金投资交易风险一、市场波动 全球影响黄金价格的因素有很多&…

51单片机中断系统

中断系统 1、中断介绍2、中断结构及相关寄存器中断满足的条件以及使用 3、外部中断实验外部中断介绍外部中断配置硬件设计软件设计 1、中断介绍 我们先来举一个生活事例&#xff1a; 你打开火&#xff0c;烧上一壶水。然后去洗衣服&#xff0c;在洗衣服的过程中&#xff0c;突…