使用JTree

    技术2022-05-11  46

    10-1:使用JTree组件:   java.lang.Object     --java.awt.Component      --java.awt.Container       --javax.swing.JComponent        --javax.swing.JTreeJTree构造函数:JTree():建立一棵系统默认的树。JTree(Hashtable value):利用Hashtable建立树,不显示root node(根节点).JTree(Object[] value):利用Object Array建立树,不显示root node.JTree(TreeModel newModel):利用TreeModel建立树。JTree(TreeNode root):利用TreeNode建立树。JTree(TreeNode root,boolean asksAllowsChildren):利用TreeNode建立树,并决定是否允许子节点的存在.JTree(Vector value):利用Vector建立树,不显示root node.

    范例:InitalTree.java

    import javax.swing.*;import java.awt.*;import java.awt.event.*;

    public class InitalTree{  public InitalTree(){          JFrame f=new JFrame("TreeDemo");          Container contentPane=f.getContentPane();                    JTree tree=new JTree();          JScrollPane scrollPane=new JScrollPane();          scrollPane.setViewportView(tree);                    contentPane.add(scrollPane);          f.pack();          f.setVisible(true);          f.addWindowListener(new WindowAdapter(){                   public void windowClosing(WindowEvent e){                     System.exit(0);                           }          });  }                  public static void main(String[] args){           new InitalTree();  }}

    10-2:以Hashtable构造JTree:   上面的例子对我们并没有裨的帮助,因为各个节点的数据均是java的默认值,而非我们自己设置的。因此我们需利用其他JTree构造函数来输入我们想要的节点数据。以下范例我们以Hashtable当作JTree的数据输入:范例:TreeDemo1.java

    import javax.swing.*;import java.awt.*;import java.awt.event.*;import java.util.*;

    public class TreeDemo1{  public TreeDemo1(){    JFrame f=new JFrame("TreeDemo1");    Container contentPane=f.getContentPane();        String[] s1={"公司文件","个人信件","私人文件"};            String[] s2={"本机磁盘(C:)","本机磁盘(D:)","本机磁盘(E:)"};    String[] s3={"奇摩站","职棒消息","网络书店"};        Hashtable hashtable1=new Hashtable();    Hashtable hashtable2=new Hashtable();    hashtable1.put("我的公文包",s1);    hashtable1.put("我的电脑",s2);    hashtable1.put("收藏夹",hashtable2);    hashtable2.put("网站列表",s3);        Font font = new Font("Dialog", Font.PLAIN, 12);    Enumeration keys = UIManager.getLookAndFeelDefaults().keys();   /**定义widnows界面**/    while (keys.hasMoreElements()) {         Object key = keys.nextElement();         if (UIManager.get(key) instanceof Font) {             UIManager.put(key, font);         }   }    try{      UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");     }catch(Exception el){      System.exit(0);     }   /**定义widnows界面**/    JTree tree=new JTree(hashtable1);    JScrollPane scrollPane=new JScrollPane();    scrollPane.setViewportView(tree);          contentPane.add(scrollPane);          f.pack();          f.setVisible(true);          f.addWindowListener(new WindowAdapter(){                   public void windowClosing(WindowEvent e){                     System.exit(0);                           }          });  }                  public static void main(String[] args){           new TreeDemo1();  }}

    纯XP界面的设置:

    10-3:以TreeNode构造JTree:   JTree上的每一个节点就代表一个TreeNode对象,TreeNode本身是一个Interface,里面定义了7个有关节点的方法,例如判断是否为树叶节点、有几个子节点(getChildCount())、父节点为何(getparent())等等、这些方法的定义你可以在javax.swing.tree的package中找到,读者可自行查阅java api文件。在实际的应用上,一般我们不会直接实作此界面,而是采用java所提供的DefaultMutableTreeMode类,此类是实作MutableTreeNode界面而来,并提供了其他许多实用的方法。MutableTreeNode本身也是一个Interface,且继承了TreeNode界面此类主要是定义一些节点的处理方式,例如新增节点(insert())、删除节点(remove())、设置节点(setUserObject())等。整个关系如下图:    TreeNode----extends--->MutableTreeNode---implements---DefaultMutableTreeNode

      接下来我们来看如何利DefaultMutableTreeNode来建立JTree,我们先来看DefaultMutableTreeNode的构造函数:

    DefaultMutableTreeNode构造函数:DefaultMutableTreeNode():建立空的DefaultMutableTreeNode对象。DefaultMutableTreeNode(Object userObject):建立DefaultMutableTreeNode对象,节点为userObject对象。DefaultMutableTreeNode(Object userObject,Boolean allowsChildren):建立DefaultMutableTreeNode对象,节点为userObject对                                象并决定此节点是否允许具有子节点。  以下为利用DefaultMutableTreeNode建立JTree的范例:TreeDemo2.java    此程序"资源管理器"为此棵树的根节点.import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.tree.*;public class TreeDemo2{  public TreeDemo2(){    JFrame f=new JFrame("TreeDemo2");    Container contentPane=f.getContentPane();        DefaultMutableTreeNode root=new DefaultMutableTreeNode("资源管理器");            DefaultMutableTreeNode node1=new DefaultMutableTreeNode("我的公文包");    DefaultMutableTreeNode node2=new DefaultMutableTreeNode("我的电脑");    DefaultMutableTreeNode node3=new DefaultMutableTreeNode("收藏夹");    DefaultMutableTreeNode node4=new DefaultMutableTreeNode("Readme");    root.add(node1);    root.add(node2);    root.add(node3);    root.add(node4);        DefaultMutableTreeNode leafnode=new DefaultMutableTreeNode("公司文件");    node1.add(leafnode);    leafnode=new DefaultMutableTreeNode("私人文件");    node1.add(leafnode);    leafnode=new DefaultMutableTreeNode("个人信件");        leafnode=new DefaultMutableTreeNode("本机磁盘(C:)");    node2.add(leafnode);    leafnode=new DefaultMutableTreeNode("本机磁盘(D:)");    node2.add(leafnode);    leafnode=new DefaultMutableTreeNode("本机磁盘(E:)");    node2.add(leafnode);        DefaultMutableTreeNode node31=new DefaultMutableTreeNode("网站列表");    node3.add(node31);        leafnode=new DefaultMutableTreeNode("奇摩站");    node31.add(leafnode);    leafnode=new DefaultMutableTreeNode("职棒消息");    node31.add(leafnode);    leafnode=new DefaultMutableTreeNode("网络书店");    node31.add(leafnode);        JTree tree=new JTree(root);    JScrollPane scrollPane=new JScrollPane();    scrollPane.setViewportView(tree);        contentPane.add(scrollPane);          f.pack();          f.setVisible(true);          f.addWindowListener(new WindowAdapter(){                   public void windowClosing(WindowEvent e){                     System.exit(0);                           }          });  }                  public static void main(String[] args){           new TreeDemo2();  }  }

    10-4:以TreeModel构造JTree.   除了以节点的观念(TreeNode)建立树之外,你可以用data model的模式建立树。树的data model称为TreeModel,用此模式的好处是可以触发相关的树事件,来处理树可能产生的一些变动。TreeModel是一个interface,里面定义了8种方法;如果你是一个喜欢自己动手做的人,或是你想显示的数据格式很复杂,你可以考虑直接实作TreeModel界面中所定义的方法来构造出JTree.TreeModel界面的方法如下所示:TreeModel方法:void      addTreeModelListener(TreeModelListener l):增加一个TreeModelListener来监控TreeModelEvent事件。Object    getChild(Object parent,int index):返回子节点。int       getChildCount(Object parent):返回子节点数量.int       getIndexOfChild(Object parent,Object child):返回子节点的索引值。Object    getRoot():返回根节点。boolean   isLeaf(Object node):判断是否为树叶节点。void      removeTreeModelListener(TreeModelListener l):删除TreeModelListener。void      valueForPathChanged(TreePath path,Object newValue):当用户改变Tree上的值时如何应对。

       你可以实作出这8种方法,然后构造出自己想要的JTree,不过在大部份的情况下我们通常不会这样做,毕竟要实作出这8种方法不是件很轻松的事,而且java本身也提供了一个默认模式,叫做DefaultTreeModel,这个类已经实作了TreeModel界面,也另外提供许多实用的方法。利用这个默认模式,我们便能很方便的构造出JTree出来了。下面为DefaultTreeModel的构造函数与范例:DefaultTreeModel构造函数:DefaultTreeModel(TreeNode root):建立DefaultTreeModel对象,并定出根节点。DefaultTreeModel(TreeNode root,Boolean asksAllowsChildren):建立具有根节点的DefaultTreeModel对象,并决定此节点是否允                       许具有子节点。

    import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.tree.*;import com.incors.plaf.alloy.*;//组件的下载网http://www.incors.com/lookandfeel//*将alloy.jar放在c:/j2sdk1.4.0/jre/lib/ext/目录下.*/public class TreeDemo3{    public TreeDemo3()    {        JFrame f = new JFrame("TreeDemo");        Container contentPane = f.getContentPane();                        DefaultMutableTreeNode root = new DefaultMutableTreeNode("资源管理器");        DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("我的公文包");        DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的电脑");        DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夹");        DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");                DefaultTreeModel treeModel = new DefaultTreeModel(root);

            /*DefaultTreeModel类所提供的insertNodeInto()方法加入节点到父节点的数量.         *利用DefaultMutableTreeNode类所提供的getChildCount()方法取得目前子节点的数量.         */        treeModel.insertNodeInto(node1, root, root.getChildCount());        treeModel.insertNodeInto(node2, root, root.getChildCount());        treeModel.insertNodeInto(node3, root, root.getChildCount());        treeModel.insertNodeInto(node4, root, root.getChildCount());                DefaultMutableTreeNode leafnode = new                 DefaultMutableTreeNode("公司文件");

            //DefaultTreeModel类所提供的insertNodeInto()方法加入节点到父节点的数量.        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());        leafnode = new DefaultMutableTreeNode("个人信件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());        leafnode = new DefaultMutableTreeNode("私人文件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());                leafnode = new DefaultMutableTreeNode("本机磁盘(C:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());        leafnode = new DefaultMutableTreeNode("本机磁盘(D:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());        leafnode = new DefaultMutableTreeNode("本机磁盘(E:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());                DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("网站列表");        treeModel.insertNodeInto(node31, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("奇摩站");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("职棒消息");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("网络书店");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        try {           LookAndFeel alloyLnF = new AlloyLookAndFeel();               UIManager.setLookAndFeel(alloyLnF);        } catch (UnsupportedLookAndFeelException ex) {        // You may handle the exception here        }         // this line needs to be implemented in order to make JWS work properly          UIManager.getLookAndFeelDefaults().put("ClassLoader", getClass().getClassLoader());                //以TreeModel建立JTree。        JTree tree = new JTree(treeModel);        /*改变JTree的外观**/          tree.putClientProperty("JTree.lineStyle","Horizontal");        /*改变JTree的外观**/        JScrollPane scrollPane = new JScrollPane();        scrollPane.setViewportView(tree);                contentPane.add(scrollPane);        f.pack();        f.setVisible(true);                f.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });

        }

        public static void main(String args[]) {            new TreeDemo3();    }}10-5:改变JTree的外观:你可以使用JComponent所提供的putClientProperty(Object key,Object value)方法来设置java默认的JTree外观,设置方式共有3种:1.tree.putClientProperty("JTree.lineStyle","None"):java默认值。2.tree.putClientProperty("JTree.lineStyle","Horizontal"):使JTree的文件夹间具有水平分隔线。3.tree.putClientProperty("JTree.lineStyle","Angled"):使JTree具有类似Windows文件管理器的直角连接线。  具体怎样做,可看上例.

    10-6:更换JTree节点图案:  JTree利用TreeCellRenderer界面来运行绘制节点的工作,同样的,你不需要直接支实作这个界面所定义的方法,因为java本身提供一个已经实作好的类来给我们使用,此类就是DefaultTreeCellRenderer,你可以在javax.swing.tree package中找到此类所提供的方法。下面为使用DefaultTreeCellRenderer更改节点图案的一个例子:

    import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.tree.*;import com.incors.plaf.alloy.*;

    public class TreeDemo4{   public TreeDemo4(){     JFrame f=new JFrame("TreeDemo");     Container contentPane=f.getContentPane();             DefaultMutableTreeNode root = new DefaultMutableTreeNode("资源管理器");        DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("我的公文包");        DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的电脑");        DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夹");        DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");        DefaultTreeModel treeModel = new DefaultTreeModel(root);        treeModel.insertNodeInto(node1, root, root.getChildCount());        treeModel.insertNodeInto(node2, root, root.getChildCount());        treeModel.insertNodeInto(node3, root, root.getChildCount());        treeModel.insertNodeInto(node4, root, root.getChildCount());                DefaultMutableTreeNode leafnode = new                 DefaultMutableTreeNode("公司文件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());        leafnode = new DefaultMutableTreeNode("个人信件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());        leafnode = new DefaultMutableTreeNode("私人文件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());                leafnode = new DefaultMutableTreeNode("本机磁盘(C:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());        leafnode = new DefaultMutableTreeNode("本机磁盘(D:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());        leafnode = new DefaultMutableTreeNode("本机磁盘(E:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());                DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("网站列表");        treeModel.insertNodeInto(node31, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("奇摩站");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("职棒消息");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("网络书店");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        try {           LookAndFeel alloyLnF = new AlloyLookAndFeel();               UIManager.setLookAndFeel(alloyLnF);        } catch (UnsupportedLookAndFeelException ex) {        // You may handle the exception here        }         // this line needs to be implemented in order to make JWS work properly          UIManager.getLookAndFeelDefaults().put("ClassLoader", getClass().getClassLoader());

            JTree tree = new JTree(treeModel);        tree.setRowHeight(20);        DefaultTreeCellRenderer cellRenderer=(DefaultTreeCellRenderer)tree.getCellRenderer();        cellRenderer.setLeafIcon(new ImageIcon("..//icons//leaf.gif"));        cellRenderer.setOpenIcon(new ImageIcon("..//icons//open.gif"));        cellRenderer.setClosedIcon(new ImageIcon("..//icons//close.gif"));                cellRenderer.setFont(new Font("宋体",Font.PLAIN,12));//设置字体.        cellRenderer.setBackgroundNonSelectionColor(Color.white);        cellRenderer.setBackgroundSelectionColor(Color.yellow);        cellRenderer.setBorderSelectionColor(Color.red);        /*设置选时或不选时,文字的变化颜色         */        cellRenderer.setTextNonSelectionColor(Color.black);        cellRenderer.setTextSelectionColor(Color.blue);                JScrollPane scrollPane=new JScrollPane();        scrollPane.setViewportView(tree);                contentPane.add(scrollPane);        f.pack();        f.setVisible(true);                f.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });

        }

        public static void main(String args[]) {            new TreeDemo4();    }}Window Xp界面:

    import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.tree.*;import com.incors.plaf.alloy.*;public class TreeDemo3{    public TreeDemo3()    {       //设置成Alloy界面样式        try {           AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");           LookAndFeel alloyLnF = new AlloyLookAndFeel();             JFrame.setDefaultLookAndFeelDecorated(true);             UIManager.setLookAndFeel(alloyLnF);        } catch (UnsupportedLookAndFeelException ex) {        // You may handle the exception here        }         // this line needs to be implemented in order to make JWS work properly        UIManager.getLookAndFeelDefaults().put("ClassLoader", getClass().getClassLoader());                   //JDialog.setDefaultLookAndFeelDecorated(true);        JFrame f = new JFrame("firstTree");               Container contentPane = f.getContentPane();       // if (contentPane instanceof JComponent) {        //   ((JComponent) contentPane).setMinimumSize(new Dimension(100, 100));        //}       // Container contentPane = f.getContentPane();                        DefaultMutableTreeNode root = new DefaultMutableTreeNode("资源管理器");        DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("我的公文包");        DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的电脑");        DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夹");        DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");                DefaultTreeModel treeModel = new DefaultTreeModel(root);        treeModel.insertNodeInto(node1, root, root.getChildCount());        treeModel.insertNodeInto(node2, root, root.getChildCount());        treeModel.insertNodeInto(node3, root, root.getChildCount());        treeModel.insertNodeInto(node4, root, root.getChildCount());                DefaultMutableTreeNode leafnode = new                 DefaultMutableTreeNode("公司文件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());        leafnode = new DefaultMutableTreeNode("个人信件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());        leafnode = new DefaultMutableTreeNode("私人文件");        treeModel.insertNodeInto(leafnode, node1, node1.getChildCount());                leafnode = new DefaultMutableTreeNode("本机磁盘(C:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());        leafnode = new DefaultMutableTreeNode("本机磁盘(D:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());        leafnode = new DefaultMutableTreeNode("本机磁盘(E:)");        treeModel.insertNodeInto(leafnode, node2, node2.getChildCount());                DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("网站列表");        treeModel.insertNodeInto(node31, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("奇摩站");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("职棒消息");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());        leafnode = new DefaultMutableTreeNode("网络书店");        treeModel.insertNodeInto(leafnode, node3, node3.getChildCount());

            JTree tree = new JTree(treeModel);        /*改变JTree的外观**/        //  tree.putClientProperty("JTree.lineStyle","Horizontal");        /*改变JTree的外观**/        JScrollPane scrollPane = new JScrollPane();        scrollPane.setViewportView(tree);                contentPane.add(scrollPane);        f.pack();        f.setVisible(true);                f.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });

        }

        public static void main(String args[]) {            new TreeDemo3();    }}

    10-7:JTree的事件处理模式:    在此节中,我们将详细介绍JTree两个常用的事件与处理,分别是TreeModeEvent与TreeSelectionEvent.10-7-1:处理TreeModeEvent事件:  当树的结构上有任何改变时,例如节点值改变了、新增节点、删除节点等,都会TreeModelEvent事件,要处理这样的事件必须实作TreeModelListener界面,此界面定义了4个方法,如下所示:TreeModelListener方法:Void              treeNodesChanged(TreeModelEvent e):当节点改变时系统就会云调用这个方法。Void              treeNodesInserted(TreeModelEvent e):当新增节时系统就会去调用这个方法。Void              treeNodesRemoved(TreeModeEvent e):当删除节点时系统就会去调用这个方法。Void              treeStructureChanged(TreeModelEvent e):当树结构改变时系统就会去调用这个方法。

      TreeModelEvent类本身提供了5个方法,帮我们取得事件的信息,如下所示:

    TreeModelEvent方法:int[]                getChildIndices():返回子节点群的索引值。Object[]             getChildren():返回子节点群.Object[]             getPath():返回Tree中一条path上(从root nod到leaf node)的节点。TreePath             getTreePath():取得目前位置的Tree Path.String               toString():取得蝗字符串表示法.      由TreeModelEvent的getTreePath()方法就可以得到TreePath对象,此对象就能够让我们知道用户目前正选哪一个节点,TreePath类最常用的方法为:     public  Object getLastPathComponent():取得最深(内)层的节点。     public int    getPathCount():取得此path上共有几个节点.    我们来看下面这个例子,用户可以在Tree上编辑节点,按下[Enter]键后就可以改变原有的值,并将改变的值显示在下面的JLabel中:

    import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.tree.*;import com.incors.plaf.alloy.*;import com.incors.plaf.alloy.themes.bedouin.*;

    public class TreeDemo5 implements TreeModelListener{    JLabel label = null;    String nodeName = null; //原有节点名称        public TreeDemo5()    {        try {                AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");                AlloyTheme theme = new BedouinTheme();//设置界面的外观,手册中共有5种样式                LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);            UIManager.setLookAndFeel(alloyLnF);        } catch (UnsupportedLookAndFeelException ex) {        // You may handle the exception here        }         // this line needs to be implemented in order to make JWS work properly        UIManager.getLookAndFeelDefaults().put("ClassLoader", getClass().getClassLoader());        JFrame f = new JFrame("TreeDemo");        Container contentPane = f.getContentPane();                DefaultMutableTreeNode root = new DefaultMutableTreeNode("资源管理器");        DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("文件夹");        DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("我的电脑");        DefaultMutableTreeNode node3 = new DefaultMutableTreeNode("收藏夹");        DefaultMutableTreeNode node4 = new DefaultMutableTreeNode("Readme");        root.add(node1);        root.add(node2);        root.add(node3);        root.add(node4);                DefaultMutableTreeNode leafnode = new DefaultMutableTreeNode("公司文件");        node1.add(leafnode);        leafnode = new DefaultMutableTreeNode("个人信件");        node1.add(leafnode);        leafnode = new DefaultMutableTreeNode("私人文件");        node1.add(leafnode);                leafnode = new DefaultMutableTreeNode("本机磁盘(C:)");        node2.add(leafnode);        leafnode = new DefaultMutableTreeNode("本机磁盘(D:)");        node2.add(leafnode);        leafnode = new DefaultMutableTreeNode("本机磁盘(E:)");        node2.add(leafnode);                DefaultMutableTreeNode node31 = new DefaultMutableTreeNode("网站列表");        node3.add(node31);                leafnode = new DefaultMutableTreeNode("天勤网站");        node31.add(leafnode);        leafnode = new DefaultMutableTreeNode("足球消息");        node31.add(leafnode);        leafnode = new DefaultMutableTreeNode("网络书店");        node31.add(leafnode);                JTree tree = new JTree(root);        tree.setEditable(true);//设置JTree为可编辑的        tree.addMouseListener(new MouseHandle());//使Tree加入检测Mouse事件,以便取得节点名称         //下面两行取得DefaultTreeModel,并检测是否有TreeModelEvent事件.        DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();        treeModel.addTreeModelListener(this);                JScrollPane scrollPane = new JScrollPane();        scrollPane.setViewportView(tree);                label = new JLabel("更改数据为: ");        contentPane.add(scrollPane,BorderLayout.CENTER);        contentPane.add(label,BorderLayout.SOUTH);        f.pack();        f.setVisible(true);                f.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });

        }    /*本方法实作TreeModelListener接口,本接口共定义四个方法,分别是TreeNodesChanged()     *treeNodesInserted()、treeNodesRemoved()、treeNodesRemoved()、     *treeStructureChanged().在此范例中我们只针对更改节点值的部份,因此只实作     *treeNodesChanged()方法.     */    public void treeNodesChanged(TreeModelEvent e) {                TreePath treePath = e.getTreePath();        System.out.println(treePath);        //下面这行由TreeModelEvent取得的DefaultMutableTreeNode为节点的父节点,而不是用户点选        //的节点,这点读者要特别注意。要取得真正的节点需要再加写下面6行代码.        DefaultMutableTreeNode node = (DefaultMutableTreeNode)treePath.getLastPathComponent();        try {            //getChildIndices()方法会返回目前修改节点的索引值。由于我们只修改一个节点,因此节点索引值就放在index[0]            //的位置,若点选的节点为root node,则getChildIndices()的返回值为null,程序下面的第二行就在处理点选root            //node产生的NullPointerException问题.            int[] index = e.getChildIndices();              //由DefaultMutableTreeNode类的getChildAt()方法取得修改的节点对象.            node = (DefaultMutableTreeNode)node.getChildAt(index[0]);        } catch (NullPointerException exc) {}        //由DefaultMutableTreeNode类getUserObject()方法取得节点的内容,或是写成node.toString()亦相同.        label.setText(nodeName+"更改数据为: "+(String)node.getUserObject());    }    public void treeNodesInserted(TreeModelEvent e) {    }    public void treeNodesRemoved(TreeModelEvent e) {    }    public void treeStructureChanged(TreeModelEvent e) {    }

        public static void main(String args[]) {            new TreeDemo5();    }    //处理Mouse点选事件    class MouseHandle extends MouseAdapter    {        public void mousePressed(MouseEvent e)         {            try{              JTree tree = (JTree)e.getSource();        //JTree的getRowForLocation()方法会返回节点的列索引值。例如本例中,“本机磁盘(D:)”的列索引值为4,此索引值        //会随着其他数据夹的打开或收起而变支,但“资源管理器”的列索引值恒为0.               int rowLocation = tree.getRowForLocation(e.getX(), e.getY());

                 /*JTree的getPathForRow()方法会取得从root node到点选节点的一条path,此path为一条直线,如程序运行的图示              *若你点选“本机磁盘(E:)”,则Tree Path为"资源管理器"-->"我的电脑"-->"本机磁盘(E:)",因此利用TreePath              *的getLastPathComponent()方法就可以取得所点选的节点.              */

                  TreePath treepath = tree.getPathForRow(rowLocation);              TreeNode treenode = (TreeNode) treepath.getLastPathComponent();                       nodeName = treenode.toString();            }catch(NullPointerException ne){}        }    }}

    注:上面的程序MouseHandle中:              int rowLocation = tree.getRowForLocation(e.getX(), e.getY());              TreePath treepath = tree.getPathForRow(rowLocation);   与:              TreePath treepath=tree.getSelectionPath();              等价,可互换。    我们将“我的电脑”改成“网上领居”:  我们再来看一个TreeModelEvent的例子,下面这个例子我们可以让用户自行增加、删除与修改节点:

    import java.awt.*;import java.awt.event.*;import javax.swing.*;import javax.swing.event.*;import javax.swing.tree.*;import com.incors.plaf.alloy.*;import com.incors.plaf.alloy.themes.bedouin.*;

    public class TreeDemo6 implements ActionListener,TreeModelListener{  JLabel label=null;  JTree  tree=null;  DefaultTreeModel treeModel=null;  String nodeName=null;//原有节点名称    public TreeDemo6(){        try {                AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");                AlloyTheme theme = new BedouinTheme();                LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);            UIManager.setLookAndFeel(alloyLnF);        } catch (UnsupportedLookAndFeelException ex) {        // You may handle the exception here        }         // this line needs to be implemented in order to make JWS work properly        UIManager.getLookAndFeelDefaults().put("ClassLoader", getClass().getClassLoader());    JFrame f=new JFrame("TreeDemo6");    Container contentPane=f.getContentPane();        DefaultMutableTreeNode root=new DefaultMutableTreeNode("资源管理器");                tree=new JTree(root);    tree.setEditable(true);    tree.addMouseListener(new MouseHandle());    treeModel=(DefaultTreeModel)tree.getModel();    treeModel.addTreeModelListener(this);        JScrollPane scrollPane=new JScrollPane();    scrollPane.setViewportView(tree);        JPanel panel=new JPanel();    JButton b=new JButton("新增节点");    b.addActionListener(this);    panel.add(b);    b=new JButton("删除节点");    b.addActionListener(this);    panel.add(b);    b=new JButton("清除所有节点");    b.addActionListener(this);    panel.add(b);        label=new JLabel("Action");    contentPane.add(panel,BorderLayout.NORTH);    contentPane.add(scrollPane,BorderLayout.CENTER);    contentPane.add(label,BorderLayout.SOUTH);    f.pack();    f.setVisible(true);    f.addWindowListener(new WindowAdapter(){            public void windowClosing(WindowEvent e){              System.exit(0);                    }    });  }          //本方法运行新增、删除、清除所有节点的程序代码.  public void actionPerformed(ActionEvent ae){           if (ae.getActionCommand().equals("新增节点")){                    DefaultMutableTreeNode parentNode=null;                    DefaultMutableTreeNode newNode=new DefaultMutableTreeNode("新节点");                    newNode.setAllowsChildren(true);                    TreePath parentPath=tree.getSelectionPath();                   //取得新节点的父节点                    parentNode=(DefaultMutableTreeNode)(parentPath.getLastPathComponent());

             //由DefaultTreeModel的insertNodeInto()方法增加新节点                    treeModel.insertNodeInto(newNode,parentNode,parentNode.getChildCount());

             //tree的scrollPathToVisible()方法在使Tree会自动展开文件夹以便显示所加入的新节点。若没加这行则加入的新节点         //会被 包在文件夹中,你必须自行展开文件夹才看得到。                    tree.scrollPathToVisible(new TreePath(newNode.getPath()));                                        label.setText("新增节点成功");           }           if (ae.getActionCommand().equals("删除节点")){                   TreePath treepath=tree.getSelectionPath();                   if (treepath!=null){          //下面两行取得选取节点的父节点.                     DefaultMutableTreeNode selectionNode=(DefaultMutableTreeNode)treepath.getLastPathComponent();                     TreeNode parent=(TreeNode)selectionNode.getParent();                     if (parent!=null)        {             //由DefaultTreeModel的removeNodeFromParent()方法删除节点,包含它的子节点。                              treeModel.removeNodeFromParent(selectionNode);                              label.setText("删除节点成功");                     }                   }                              }           if (ae.getActionCommand().equals("清除所有节点")){

            //下面一行,由DefaultTreeModel的getRoot()方法取得根节点.                   DefaultMutableTreeNode rootNode=(DefaultMutableTreeNode)treeModel.getRoot();

            //下面一行删除所有子节点.                   rootNode.removeAllChildren();  

            //删除完后务必运行DefaultTreeModel的reload()操作,整个Tree的节点才会真正被删除.                        treeModel.reload();                   label.setText("清除所有节点成功");           }  }     public void treeNodesChanged(TreeModelEvent e){             TreePath treePath=e.getTreePath();             DefaultMutableTreeNode node=(DefaultMutableTreeNode)treePath.getLastPathComponent();             try{               int[] index=e.getChildIndices();               node=(DefaultMutableTreeNode)node.getChildAt(index[0]);                     }catch(NullPointerException exc){}               label.setText(nodeName+"更改数据为:"+(String)node.getUserObject());     }           public void treeNodesInserted(TreeModelEvent e){             System.out.println("new node insered");                                }           public void treeNodesRemoved(TreeModelEvent e){             System.out.println("node deleted");                   }           public void treeStructureChanged(TreeModelEvent e){             System.out.println("Structrue changed");                   }    public static void main(String[] args){      new TreeDemo6();            }        class MouseHandle extends MouseAdapter{      public void mousePressed(MouseEvent e){         try{           JTree tree=(JTree)e.getSource();           int rowLocation=tree.getRowForLocation(e.getX(),e.getY());           TreePath treepath=tree.getPathForRow(rowLocation);                   TreeNode treenode=(TreeNode)treepath.getLastPathComponent();           nodeName=treenode.toString();                    }catch(NullPointerException ne){}      }            }}

    10-7-2:处理TreeSelectionEvent事件:    当我们在JTree上点选任何一个节点,都会触发TreeSelectionEvent事件,如果我们要处理这样的事件,必须实作TreeSelectionListener界面,此界面只定义了一个方法,那就是valueChanged()方法。    TreeSelectionEvent最常用在处理显示节点的内容,例如你在文件图标中点两下就可以看到文件的内容。在JTree中选择节点的方式共有3种,这3种情况跟选择JList上的项目是一模一样的,分别是:      DISCONTIGUOUS_TREE_SELECTION:可作单一选择,连续点选择(按住[Shift]键),不连续选择多个节点(按住[Ctrl]键),这是java默认值.      CONTINUOUS_TREE_SELECTION:按住[Shift]键,可对某一连续的节点区间作选取。      SINGLE_TREE_SELECTION:一次只能选一个节点。   你可以自行实作TreeSelectionModel制作作更复杂的选择方式,但通常是没有必要的,因为java提供了默认的选择模式类供我们使用,那就是DefaultTreeSelectionModel,利用这个类我们可以很方便的设置上面3种选择模式。   下面这个范例,当用户点选了一个文件名时,就会将文件的内容显示出来。TreeDemo7.java

    import javax.swing.*;import javax.swing.tree.*;import javax.swing.event.*;import java.awt.*;import java.awt.event.*;import java.io.*;import java.util.*;import com.incors.plaf.alloy.*;import com.incors.plaf.alloy.themes.glass.*;

    public class TreeDemo7 implements TreeSelectionListener{    JEditorPane editorPane;

        public TreeDemo7()    {        JFrame f = new JFrame("TreeDemo");        Container contentPane = f.getContentPane();        DefaultMutableTreeNode root = new DefaultMutableTreeNode("资源管理器");        DefaultMutableTreeNode node = new DefaultMutableTreeNode("TreeDemo1.java");        root.add(node);        node = new DefaultMutableTreeNode("TreeDemo2.java");        root.add(node);        node = new DefaultMutableTreeNode("TreeDemo3.java");        root.add(node);        node = new DefaultMutableTreeNode("TreeDemo4.java");        root.add(node);                JTree tree = new JTree(root);        //设置Tree的选择模式为一次只能选择一个节点        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);        //检查是否有TreeSelectionEvent事件。        tree.addTreeSelectionListener(this);

            //下面五行,JSplitPane中,左边是放含有JTree的JScrollPane,右边是放JEditorPane.        JScrollPane scrollPane1 = new JScrollPane(tree);        editorPane = new JEditorPane();        JScrollPane scrollPane2 = new JScrollPane(editorPane);        JSplitPane splitPane = new JSplitPane(        JSplitPane.HORIZONTAL_SPLIT,true, scrollPane1, scrollPane2);

            contentPane.add(splitPane);        f.pack();        f.setVisible(true);                f.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e) {                System.exit(0);            }        });    }    //本方法实作valueChanged()方法    public void valueChanged(TreeSelectionEvent e)    {        JTree tree = (JTree) e.getSource();         //利用JTree的getLastSelectedPathComponent()方法取得目前选取的节点.        DefaultMutableTreeNode selectionNode =            (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();

            String nodeName = selectionNode.toString();                //判断是否为树叶节点,若是则显示文件内容,若不是则不做任何事。        if (selectionNode.isLeaf())         {           /*取得文件的位置路径,System.getProperty("user.dir")可以取得目前工作的路径,            *System.getProperty("file.separator")是取得文件分隔符,例如在window环境的            *文件分陋符是"/",而Unix环境的文件分隔符刚好相反,是"/".利用System.getProperty()            *方法你可以取得下列的信息:            java.version                             显示java版本            java.endor                               显示java制造商            java.endor.url                           显示java制造商URL            java.home                                显示java的安装路径            java.class.version                       显示java类版本            java.class.path                          显示java classpath            os.name                                  显示操作系统名称            os.arch                                  显示操作系统结构,如x86            os.version                               显示操作系统版本            file.separator                           取得文件分隔符            path.separator                           取得路径分隔符,如Unix是以“:”表示            line.separator                           取得换行符号,如Unix是以"/n"表示            user.name                                取得用户名称            user.home                                取得用户家目录(home directory),如Windows中Administrator的家目                                                     录为c:/Documents and Settings/Administrator            user.dir                                 取得用户目前的工作目录.            */            String filepath = "file:"+System.getProperty("user.dir") +                               System.getProperty("file.separator") +                               nodeName;                                       try {               //利用JEditorPane的setPage()方法将文件内容显示在editorPane中。若文件路径错误,则会产生IOException.                 editorPane.setPage(filepath);            } catch(IOException ex) {                 System.out.println("找不到此文件");            }        }    }        public static void main(String[] args) {            SwingUtil.setLookAndFeel();        new TreeDemo7();            }}             

    class SwingUtil{  public static final void setLookAndFeel() {          try{            Font font = new Font("JFrame", Font.PLAIN, 12);            Enumeration keys = UIManager.getLookAndFeelDefaults().keys();

                while (keys.hasMoreElements()) {               Object key = keys.nextElement();               if (UIManager.get(key) instanceof Font) {                  UIManager.put(key, font);                }            }                 AlloyLookAndFeel.setProperty("alloy.isLookAndFeelFrameDecoration", "true");                AlloyTheme theme = new GlassTheme();                LookAndFeel alloyLnF = new AlloyLookAndFeel(theme);           JFrame.setDefaultLookAndFeelDecorated(true);                      UIManager.setLookAndFeel(alloyLnF);          }catch(UnsupportedLookAndFeelException ex){            ex.printStackTrace();                  }}} 


    最新回复(0)