`
zeyuphoenix
  • 浏览: 55692 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JTree--树(基本使用)

 
阅读更多
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="ProgId" content="Word.Document"> <meta name="Generator" content="Microsoft Word 12"> <meta name="Originator" content="Microsoft Word 12"> <link rel="File-List" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_filelist.xml"> <link rel="Edit-Time-Data" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_editdata.mso"> <!--[if !mso]> <style> v":* {behavior:url(#default#VML);} o":* {behavior:url(#default#VML);} w":* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);} </style> <![endif]--><link rel="themeData" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_themedata.thmx"> <link rel="colorSchemeMapping" href="file:///C:%5CDOCUME%7E1%5Cphoenix%5CLOCALS%7E1%5CTemp%5Cmsohtmlclip1%5C01%5Cclip_colorschememapping.xml"> <!--[if gte mso 9]><xml> Normal 0 false 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE </xml><![endif]--><!--[if gte mso 9]><![endif]--><style> <!-- /* Font Definitions */ @font-face {font-family:宋体; panose-1:2 1 6 0 3 1 1 1 1 1;} @font-face {font-family:"Cambria Math"; panose-1:2 4 5 3 5 4 6 3 2 4;} @font-face {font-family:Calibri; panose-1:0 0 0 0 0 0 0 0 0 0; mso-font-alt:"Times New Roman";} @font-face {font-family:""@宋体"; panose-1:2 1 6 0 3 1 1 1 1 1;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal { mso-style-parent:""; margin:0cm; margin-bottom:.0001pt; text-align:justify; text-justify:inter-ideograph; font-size:10.5pt; font-family:"Calibri","serif"; mso-bidi-font-family:"Times New Roman";} pre { mso-style-link:"HTML 预设格式 Char"; margin:0cm; margin-bottom:.0001pt; font-size:12.0pt; font-family:宋体;} span.apple-style-span {} span.HTMLChar {mso-style-name:"HTML 预设格式 Char"; mso-style-link:"HTML 预设格式"; font-family:宋体;} .MsoChpDefault { mso-bidi-font-family:"Times New Roman";} /* Page Definitions */ @page {} @page Section1 {size:595.3pt 841.9pt; margin:72.0pt 90.0pt 72.0pt 90.0pt; layout-grid:15.6pt;} div.Section1 {page:Section1;} --> </style> <!--[if gte mso 10]> <style> /* Style Definitions */ table.MsoNormalTable { mso-style-parent:""; font-size:10.5pt; font-family:"Calibri","serif";} </style> <![endif]-->

JTree也是一个分层显示数据的组件,它在Swing里复杂度算是中等,涉及的类不是很多,也没有复杂的UI,所以单独对一个树来说,构造和渲染都不难,对于树的操作比较麻烦的是拖拽和与其他组件数据交互.

对于JTree有几个比较重要的类和接口: TreeMode是一个接口,用来构建树的模型,实现这个接口之后我们可以把一些比较另类的组件抽象成一棵树,TreeTable就是这个原理实现的;TreeNode是一个接口,代表树的节点,DefaultMutableTreeNode是该接口的一个实现,我们一般构建树使用它就可以了,当然也可以继承它添加新的功能,或者实现TreeNode把节点变成其它组件; TreePath是一个类,负责节点到根的路径,一般不需要我们来修改; TreeSelectionModel是一个接口,表示树选择组件的当前状态,只是使用皆可以了,一般除非做很大的改动,否则不需要修改这个类;还有就是TreeCellRendererTreeCellEditor,它们是树的渲染器,实现特殊效果都需要实现它们;还有就是TreeUI,树的UI比较死板,很少需要修改.

由上面类和接口可以,树还是一个不是很复杂的组件的,除了基本使用外,我们一般会用到的也就是对Cell进行渲染,替换树的节点图片,或者给节点加个CheckBox这些了.

先看树的简单使用,Sun官方给我们提供了例子:

<!--[if gte vml 1]> <![endif]-->

这个例子只是简单的构建一棵树:

       // Create the root nodes.

        DefaultMutableTreeNode top = new DefaultMutableTreeNode(

                "The Java Series");

        //add node

        createNodes(top);

        // Create a tree that allows one selection at a time.

        tree = new JTree(top);

        tree.getSelectionModel().setSelectionMode(

                TreeSelectionModel.SINGLE_TREE_SELECTION);

当然我们也可以先创建树,再设置数据,这都是JTree的构造函数,本质上是没区别的,最终JTree也是通过setModel设置数据的:

tree = new JTree();

tree.setModel(treeModel);

构造完树之后还要把树放在JScollPanel,否则树显示会有问题:

        // Create the scroll pane and add the tree to it.

        JScrollPane treeView = new JScrollPane(tree);

到此为止,树就完成了,当然Sun也提供了许多方法便捷于我们操作树:

取得根节点:

     // get the tree root node

     TreeNode rootNode = (TreeNode)tree.getModel().getRoot();

取得树的数据模型:

     // get the tree model.

     DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();

取得树的某一个节点的位置:

     // get tree node path.

     TreePath nodePath = new TreePath(treeModel.getPathToRoot(node));

设置节点的展开可见和选择:

     //select the node.

     tree.setSelectionPath(nodePath);

    // Ensures that the node identified by path is currently viewable.

tree.makeVisible(nodePath);

展开后滚动至节点可见:

    // Makes sure all the path components display

tree.scrollPathToVisible(nodePath);

还有一个是设置鼠标点击展开树节点的(默认是双击,改成了0就是不可点击):

   // Sets the number of mouse clicks before a node will expand or close.

   tree.setToggleClickCount(1);

另外就是一个设置Cell的高度的,但这个方法我们一般不用,大多时候是在Renderer里设置的,因为这样设置可能有UI问题:

   // Sets the height of each cell, in pixels.

   tree.setRowHeight(15);

其它还有很多,因为JTree继承JComponent,所以它有父类的所有方法,我们通过setXXXgetXXX就可以设置了.

说完基本的设置之后,说一下JTree的事件:

JTree继承JComponent,所以它有JComponent的事件,但我们一般只关注鼠标的键盘的:

    // add mouse listener

    tree.addMouseListener(this);

    // add key listener

tree.addKeyListener(this);

然后是JTree独有的事件:

    tree.addTreeExpansionListener(this);

    tree.addTreeWillExpandListener(this);

    tree.addTreeSelectionListener(this);

分别是树节点展开(折叠)、树节点将要展开(折叠)和树节点选择事件,我们一般用的多的是addTreeExpansionListeneraddTreeSelectionListener事件:

事件处理都不是很复杂,增加监听后实现方法就可以了,需要注意的是TreeSelectionListenerMouseListener,它们有事件重叠的地方:但在树的节点点击鼠标左键时触发这两个事件,点击右键时触发鼠标事件,所以这两个事件都做监听时,处理一定要注意:

先看TreeSelectionListener的处理:

     @Override

     publicvoid valueChanged(TreeSelectionEvent event) {

然后可以取得TreePath,之后取得Node

     // Returns the current lead path.

     TreePath newPath = event.getNewLeadSelectionPath();

     TreePath oldPath = event.getOldLeadSelectionPath();

或者通过JTree取得Node

JTree tree = (JTree) event.getSource();

tree.getLastSelectedPathComponent();

再看MouseListener的处理:

      @Override

    publicvoid mouseClicked(MouseEvent e) {

鼠标组件场合比较简单,因为这个时候节点被选中:

if (SwingUtilities.isLeftMouseButton(e)

                    && e.getClickCount() == 1) {

       // Returns the last path component

       DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree

                        .getLastSelectedPathComponent();

    }

右键则要得出节点位置再处理:

     if (SwingUtilities.isRightMouseButton(e)) {

        // Returns the row for the specified location.

        int selectRow = tree.getRowForLocation(e.getX(), e.getY());

        // Returns the path for the node at the specified location.

        TreePath selectPath = tree.getPathForLocation(e.getX(), e

                        .getY());

        if (selectPath != null) {

             // set select

             tree.setSelectionPath(selectPath);

             // get tree node.

            DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) selectPath.getLastPathComponent();

      }

之后有了树和选择节点就可以做自己的业务逻辑了.

另外JTree的节点的增加、修改和删除也需要看一下,如果我们使用DefaultTreeModel的话,这些操作都很简单,通过它的insertNodeInto



removeNodeFromParentnodeChanged等方法就可以实现了,但是如果是我们自己实现的TreeModel,必须再做完数据的操作之后UpdateUI更新界面,



或者学习Sun的事件机制,触发事件然后在View层更新画面,一般都不推荐这么做,除非你的TreeModel的数据特别复杂,没办法使用
DefaultTreeModel



这个数据容器
,例如TreeTable.

到此,除了JTreeRendererEditor之外,只剩下JTree的取数据了.JTree的数据取得我们一般都是用递归,这儿写个从任何节点递归其下所有的例子:

    private List<TreeNode> treeNodeList = new ArrayList<TreeNode>();

    publicvoid getChildNodeList(TreeNode treeNode) {

        if (treeNode == null) {

            thrownew RuntimeException("error treenode.");

        }

        if (treeNodeList == null) {

            treeNodeList = new ArrayList<TreeNode>();

        }

        if (treeNode.getChildCount() >= 0) {

            for (Enumeration<TreeNode> e = treeNode.children(); e

                    .hasMoreElements();) {

                TreeNode childNode = (TreeNode) e.nextElement();

                treeNodeList.add(childNode);

                getChildNodeList(childNode);

            }

        }

    }

最后我们看一个Renderer的例子,Sun官方提供的:

<!--[if gte vml 1]> <![endif]-->

首先看它的Renderer实现,这个是直接继承DefaultTreeCellRenderer

privateclass MyRenderer extends DefaultTreeCellRenderer {

然后复写它的getTreeCellRendererComponent方法:

    @Override

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,

        boolean hasFocus) {

它的默认实现时一个JLabel,在里面我们就可以设置它的效果了,这里设置一个图片:

setIcon(tutorialIcon);

当然我们也可以继承其它组件,实现TreeCellRenderer接口,实现更多效果.

使用很简单,直接使用JTreesetCellRenderer方法就可以了:

tree.setCellRenderer(new MyRenderer(tutorialIcon));

总结,基本树的操作和呈现设置都这里就完成了,可以看出,树还是比较简单的,后面我预计还有两个主题,一个是关于JTreeRendererEditor,在那儿实现一棵树的节点的图片特性,可用与否,选择隐藏等;另外就是关于树的选择框了,其实也是RendererEditor的使用,只不过为了逻辑和应用,做的更复杂.

分享到:
评论

相关推荐

    jtree树应用

    这是jtree的基本应用程序,集合了很多方面的树状结构

    swing界面设计之JTree

    (三) 对JTree从创建到使用详解 56 (四) JTree的使用方法 57 JTreeDemo.java源程序 57 经验汇总 60 1. 初始化 60 2. 三个经常使用的取值函数 60 3. 根据node得到path: 60 4. 根据Path展开到该节点 60 5. 根据path...

    Java Swing中的表格(JTable)和树(JTree)组件使用实例

    主要介绍了Java Swing中的表格(JTable)和树(JTree)组件使用实例,本文同时讲解了表格和树的基本概念、常用方法、代码实例,需要的朋友可以参考下

    javaSE代码实例

    9.7.1 基本语法与使用 172 9.7.2 不允许进行测试的情况 174 9.8 小结 175 第10章 构造器——对象制造的工厂 176 10.1 基础知识 176 10.1.1 编写构造器的语法规则 176 10.1.2 访问限制修饰符与构造器 ...

    Java开发技术大全 电子版

    14.8.10树(JTree)使用示例518 14.8.11菜单使用示例523 14.9布局管理527 14.9.1流式布局(FlowLayout)回顾527 14.9.2边框布局(BorderLayout)使用示例528 14.9.3网格布局(GridLayout)使用示例529 14.9.4...

    JExplorerTree:纯Java中的简单文件资源管理器组件

    没有额外的依赖关系(扩展JPanel并使用JTree) 外部拖放(往返操作系统) 内部拖放(在树内) 键盘支持:F2,DELETE,ENTER CTRL + C,CTRL + V,CTRL + X(内部) CTRL + V(来自外部文件) CTRL + C(允许...

    疯狂JAVA讲义

    学生提问:当我们使用编译C程序时,不仅需要指定存放目标文件的位置,也需要指定目标文件的文件名,这里使用javac编译Java程序时怎么不需要指定目标文件的文件名呢? 13 1.5.3 运行Java程序 14 1.5.4 根据...

    Java开发技术大全(500个源代码).

    示例描述:本章演示如何开始使用JDK进行程序的开发。 HelloWorldApp.java 第一个用Java开发的应用程序。 firstApplet.java 第一个用Java开发的Applet小程序。 firstApplet.htm 用来装载Applet的网页文件 第2章 ...

    java初学者必看

    13.3.7 树(JTree) 13.3.8 文本框(JTextField)与文本区(JTextArea) 13.4 布局管理器 13.4.1 FlowLayout布局管理器 13.4.2 BorderLayout布局管理器 13.4.3 BoxLayout布局管理器 13.4.4 GridLayout布局管理器 ...

    java编写的java编辑器

    无聊时用java编写的java编辑器,主要是嫌Eclipse占用资源太大,于是用...3.基本功能均实现,只是编辑区的排版有点乱,正是下一步要做的,现在是预览版,如有需要请期待,Mains为主文件,需添加tools.jar,编辑即可运行

Global site tag (gtag.js) - Google Analytics