so true

          心懷未來,開創未來!
          隨筆 - 160, 文章 - 0, 評論 - 40, 引用 - 0
          數據加載中……

          JTree學習筆記!

          對于JTree比較重要的幾個類或接口:
          1。TreeMode是一個接口,是構建樹的模型,接口中比較重要的幾個函數是:getChild、getChildCount、getRoot、getIndexOfChild、isLeaf。如果想把一些特殊的東西抽象成一棵樹,那么就可以實現該接口,用自己構造的這個模型來創建樹JTree(TreeModel newModel)
          2。TreeNode是一個接口,代表樹的節點。DefaultMutableTreeNode是該接口的一個實現,可以直接用來創建樹的節點。
          3。TreePath是一個類,負責節點到根的路徑
          4。TreeSelectionModel是一個接口,表示樹選擇組件的當前狀態。DefaultTreeSelectionModel類是該接口的一個實現類。

          構造方法摘要
          JTree()
                    返回帶有示例模型的 JTree。
          JTree(Hashtable<?,?> value)
                    返回從 Hashtable 創建的 JTree,它不顯示根。
          JTree(Object[] value)
                    返回 JTree,指定數組的每個元素作為不被顯示的新根節點的子節點。
          JTree(TreeModel newModel)
                    返回 JTree 的一個實例,它顯示根節點 - 使用指定的數據模型創建樹。
          JTree(TreeNode root)
                    返回 JTree,指定的 TreeNode 作為其根,它顯示根節點。
          JTree(TreeNode root, boolean asksAllowsChildren)
                    返回 JTree,指定的 TreeNode 作為其根,它用指定的方式顯示根節點,并確定節點是否為葉節點。
          JTree(Vector<?> value)
                    返回 JTree,指定 Vector 的每個元素作為不被顯示的新根節點的子節點。

          常用方法:
          1。得到模型:
          getModel()或(DefaultTreeModel)getModel()
          2。得到根:
          getModel().getRoot()或(DefaultMutableTreeNode)getModel().getRoot()
          3。根據node得到path:
          TreePath visiblePath = new TreePath(((DefaultTreeModel)getModel()).getPathToRoot(node))
          4。根據Path展開到該節點:
          makeVisible(visiblePath)
          5。根據path設定該節點選定
          tree.setSelectionPath(visiblePath)
          6。滾動到可見位置:
          scrollRowToVisible(int row)
          7。展開樹<從根展開或從某一個節點展開>
          關于JTree的展開
             // If expand is true, expands all nodes in the tree.
             // Otherwise, collapses all nodes in the tree.
           public static void expandAll(JTree tree, boolean expand) {
            TreeNode root = (TreeNode) tree.getModel().getRoot();

            // Traverse tree from root
            expandAll(tree, new TreePath(root), expand);
           }

           private static void expandAll(JTree tree, TreePath parent, boolean expand) {
            // Traverse children
            TreeNode node = (TreeNode) parent.getLastPathComponent();
            if (node.getChildCount() >= 0) {
             for (Enumeration e = node.children(); e.hasMoreElements();) {
              TreeNode n = (TreeNode) e.nextElement();
              TreePath path = parent.pathByAddingChild(n);
              expandAll(tree, path, expand);
             }
            }

            // Expansion or collapse must be done bottom-up
            if (expand) {
             tree.expandPath(parent);
            } else {
             tree.collapsePath(parent);
            }
           }
          8。遍歷樹的所有節點<從根遍歷或從某一個節點遍歷>
          public static void visitAllNodes(JTree tree) {
            TreeNode root = (TreeNode) tree.getModel().getRoot();
            visitAllNodes(tree,root);
           }

           public static void visitAllNodes(JTree tree,TreeNode node) {
            // node is visited exactly once
            //you can do your things about this node,such as:
            tree.makeVisible(new TreePath(
              ((DefaultTreeModel)tree.getModel()).getPathToRoot(node)));

            if (node.getChildCount() >= 0) {
             for (Enumeration e = node.children(); e.hasMoreElements();) {
              TreeNode n = (TreeNode) e.nextElement();
              visitAllNodes(tree,n);
             }
            }
           }
          9。遍歷樹已經展開的節點<從根遍歷或從某一個節點遍歷>
          // Traverse all expanded nodes in tree
           public static void visitAllExpandedNodes(JTree tree) {
            TreeNode root = (TreeNode) tree.getModel().getRoot();
            visitAllExpandedNodes(tree, new TreePath(root));
           }

           public static void visitAllExpandedNodes(JTree tree, TreePath parent) {
            // Return if node is not expanded
            if (!tree.isVisible(parent)) {
             return;
            }

            // node is visible and is visited exactly once
            TreeNode node = (TreeNode) parent.getLastPathComponent();
            //you can do your things about this node,such as:
            System.out.println(node.toString());

            // Visit all children
            if (node.getChildCount() >= 0) {
             for (Enumeration e = node.children(); e.hasMoreElements();) {
              TreeNode n = (TreeNode) e.nextElement();
              TreePath path = parent.pathByAddingChild(n);
              visitAllExpandedNodes(tree, path);
             }
            }
           }

          一個較為完整的練習:
          import java.awt.Dimension;
          import java.awt.Color;
          import java.awt.event.MouseAdapter;
          import java.awt.event.MouseEvent;
          import java.util.Enumeration;
          import javax.swing.JFrame;
          import javax.swing.JPanel;
          import javax.swing.JScrollPane;
          import javax.swing.JTree;
          import javax.swing.BoxLayout;
          import javax.swing.tree.DefaultMutableTreeNode;
          import javax.swing.tree.DefaultTreeModel;
          import javax.swing.tree.TreeNode;
          import javax.swing.tree.TreePath;

          public class JTreeDemo {

           public static void expandAll(JTree tree, boolean expand) {
            TreeNode root = (TreeNode) tree.getModel().getRoot();

            // Traverse tree from root
            expandAll(tree, new TreePath(root), expand);
           }

           private static void expandAll(JTree tree, TreePath parent, boolean expand) {
            // Traverse children
            TreeNode node = (TreeNode) parent.getLastPathComponent();
            if (node.getChildCount() >= 0) {
             for (Enumeration e = node.children(); e.hasMoreElements();) {
              TreeNode n = (TreeNode) e.nextElement();
              TreePath path = parent.pathByAddingChild(n);
              expandAll(tree, path, expand);
             }
            }

            // Expansion or collapse must be done bottom-up
            if (expand) {
             tree.expandPath(parent);
            } else {
             tree.collapsePath(parent);
            }
           }

           
           public static void visitAllNodes(JTree tree) {
            TreeNode root = (TreeNode) tree.getModel().getRoot();
            visitAllNodes(tree,root);
           }

           public static void visitAllNodes(JTree tree,TreeNode node) {
            // node is visited exactly once
            //you can do your things about this node,such as:
            tree.makeVisible(new TreePath(
              ((DefaultTreeModel)tree.getModel()).getPathToRoot(node)));

            if (node.getChildCount() >= 0) {
             for (Enumeration e = node.children(); e.hasMoreElements();) {
              TreeNode n = (TreeNode) e.nextElement();
              visitAllNodes(tree,n);
             }
            }
           }

           // Traverse all expanded nodes in tree
           public static void visitAllExpandedNodes(JTree tree) {
            TreeNode root = (TreeNode) tree.getModel().getRoot();
            visitAllExpandedNodes(tree, new TreePath(root));
           }

           public static void visitAllExpandedNodes(JTree tree, TreePath parent) {
            // Return if node is not expanded
            if (!tree.isVisible(parent)) {
             return;
            }

            // node is visible and is visited exactly once
            TreeNode node = (TreeNode) parent.getLastPathComponent();
            //you can do your things about this node,such as:
            System.out.println(node.toString());

            // Visit all children
            if (node.getChildCount() >= 0) {
             for (Enumeration e = node.children(); e.hasMoreElements();) {
              TreeNode n = (TreeNode) e.nextElement();
              TreePath path = parent.pathByAddingChild(n);
              visitAllExpandedNodes(tree, path);
             }
            }
           }
           public static JTree tr;
           public static void main(String[] args) {

            // 構造函數:JTree()
            JTree example1 = new JTree();
            tr=example1;
            example1.setBackground(Color.lightGray);
            example1.addMouseListener(new MouseAdapter(){
             public void mouseClicked(MouseEvent me){
              try{
               visitAllNodes(tr);
               Thread.sleep(2000);
               System.out.println(tr.getPathForRow(1).toString());
               expandAll(tr,tr.getPathForRow(1),false);
               Thread.sleep(2000);
               visitAllExpandedNodes(tr);
              }catch(InterruptedException e){
               e.printStackTrace();
              }
             }
            });

            // 構造函數:JTree(Object[] value)
            Object[] letters = { " a ", " b ", " c ", " d ", " e " };
            JTree example2 = new JTree(letters);

            // 構造函數:JTree(TreeNode root)(TreeNode空)
            // 用空結點創建樹
            DefaultMutableTreeNode node1 = new DefaultMutableTreeNode(); // 定義樹結點
            JTree example3 = new JTree(node1); // 用此樹結點做參數調用 JTree的構造函數創建含有一個根結點的樹

            // 構造函數:JTree(TreeNode root)(同上,只是TreeNode非空)
            // 用一個根結點創建樹
            DefaultMutableTreeNode node2 = new DefaultMutableTreeNode(" Color ");
            JTree example4 = new JTree(node2); // 結點不可以顏色,默認為白面黑字
            example4.setBackground(Color.lightGray);

            // 構造函數:JTree(TreeNode root, boolean
            // asksAllowsChildren)(同上,只是TreeNode又有不同)
            // 使用DefaultMutableTreeNode類先用一個根結點創建樹,設置為可添加孩子結點,再添加孩子結點
            DefaultMutableTreeNode color = new DefaultMutableTreeNode(" Color ",
              true);
            DefaultMutableTreeNode gray = new DefaultMutableTreeNode(" Gray ");
            color.add(gray);
            color.add(new DefaultMutableTreeNode(" Red "));
            gray.add(new DefaultMutableTreeNode(" Lightgray "));
            gray.add(new DefaultMutableTreeNode(" Darkgray "));
            color.add(new DefaultMutableTreeNode(" Green "));
            JTree example5 = new JTree(color);

            // 構造函數:JTree(TreeNode root)(同上,只是TreeNode非空)
            // 通過逐個添加結點創建樹
            DefaultMutableTreeNode biology = new DefaultMutableTreeNode(" Biology ");
            DefaultMutableTreeNode animal = new DefaultMutableTreeNode(" Animal ");
            DefaultMutableTreeNode mammal = new DefaultMutableTreeNode(" Mammal ");
            DefaultMutableTreeNode horse = new DefaultMutableTreeNode(" Horse ");
            mammal.add(horse);
            animal.add(mammal);
            biology.add(animal);
            JTree example6 = new JTree(biology);
            horse.isLeaf();
            horse.isRoot();

            // 構造函數:JTree(TreeModel newModel)
            // 用DefaultMutableTreeNodel類定義一個結點再用這個結點做參數定義一個用DefaultTreeMode
            // 創建一個樹的模型,再用JTree的構造函數創建一個樹

            DefaultMutableTreeNode root = new DefaultMutableTreeNode(" Root1 ");
            DefaultMutableTreeNode child1 = new DefaultMutableTreeNode(" Child1 ");
            DefaultMutableTreeNode child11 = new DefaultMutableTreeNode(" Child11 ");
            DefaultMutableTreeNode child111 = new DefaultMutableTreeNode(
              " Child111 ");
            root.add(child1);
            child1.add(child11);
            child11.add(child111);

            DefaultTreeModel model = new DefaultTreeModel(root);

            JTree example7 = new JTree(model);

            JPanel panel = new JPanel();
            panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
            panel.setPreferredSize(new Dimension(700, 400));
            panel.add(new JScrollPane(example1)); // JTree必須放在JScrollPane上
            panel.add(new JScrollPane(example2));
            panel.add(new JScrollPane(example3));
            panel.add(new JScrollPane(example4));
            panel.add(new JScrollPane(example5));
            panel.add(new JScrollPane(example6));
            panel.add(new JScrollPane(example7));

            JFrame frame = new JFrame(" JTreeDemo ");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setContentPane(panel);
            frame.pack();
            frame.setVisible(true);
           }
          }

          另外一個例子,在該例子中筆者使用基于本機目錄構建的模型來構建樹:

          /**
           * 查API時發現1.4FileSystemView這個東東多了一些功能,
           * 無聊地寫了這個文件目錄樹
           *
           * 聲明:使用j2sdk1.4
           * 建議:實現自己的File類,以過濾掉一般文件,只剩下目錄
           * 缺點:gui慢得要死,swing的通病?(my pc==256ddr,thunderbird900,xp)
           */

          import java.awt.Component;
          import java.io.*;
          import javax.swing.*;
          import javax.swing.event.TreeModelListener;
          import javax.swing.filechooser.FileSystemView;
          import javax.swing.tree.*;

          public class Test {

           /**
            * javax.swing.filechooser.FileSystemView在這個程序里很重要,
            * 用法參考j2sdk1.4 API文檔
            * 切記,1.4 not 1.3!!!!!!!!
            */
           private static FileSystemView fileView;
           int a=BB;
           static int BB=34;

           /**
            *在這里使用了Singleton模式
            * 不過似乎沒什么破用
            */
           static FileSystemView getFileView() {
            if (fileView == null)
             fileView = FileSystemView.getFileSystemView();
            return fileView;
           }
            
           public static void main(String[] args) throws Exception {
            //如果加入下面這句,會亂碼.i wonder why
            UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());

            //initial frame
            JFrame frame = new JFrame();
            frame.setSize(400, 300);
            //關閉窗口時退出程序
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            //initial tree with customer TreeModel
            
            JTree tree = new JTree(new CustomTreeModel());

            //set customer TreeCellRenderer
            tree.setCellRenderer(new CustomTreeCellRenderer());
            frame.getContentPane().add(new JScrollPane(tree));
            frame.setVisible(true);
           }
          }

          class CustomTreeModel implements TreeModel {
           private FileSystemView fileView;

           public CustomTreeModel() {
            fileView = Test.getFileView();
           }

           //返回根節點
           public Object getRoot() {
            return fileView.getRoots()[0];
           }

           //返回父節點parent的第index個子節點,index以0開始
           public Object getChild(Object _parent, int index) {
            File parent = (File) _parent;
            return parent.listFiles()[index];
           }

           //返回父節點parent下,子節點child的位置,與上面的方法正好相反
           public int getIndexOfChild(Object parent, Object child) {
            File[] files = ((File) parent).listFiles();
            for (int i = 0; i < files.length; i++) {
             if (files[i].equals(child))
              return i;
            }
            return -1;
           }

           //返回父節點parent的子節點數
           public int getChildCount(Object parent) {
            File[] files = ((File) parent).listFiles();
            /**
             *maybe driver not ready,ie cdrom
             *then files is null
             */
            if (files == null)
             return -1;

            return files.length;
           }

           //是否葉節點
           public boolean isLeaf(Object node) {
            return ((File) node).isFile();
           }

           public void valueForPathChanged(TreePath path, Object newValue) {
           }

           /**
            *下面的方法要實現,則要涉及比較復雜的事件處理
            *如果有興趣,
            *可以簡單的使用javax.swing.EventListenerList來實現
            */
           public void addTreeModelListener(TreeModelListener l) {
           }

           public void removeTreeModelListener(TreeModelListener l) {
           }

          }

          /**
           * 如果沒有安裝自己的CellRenderer
           * JTree默認的CellRenderer就是JLabel
           * 它只是簡單的setText(node.toString)
           * CustomeTreeCellRenderer也只是簡單取回
           * windows默認的文件圖標和文件名,裝到JLabel上去
           */

          class CustomTreeCellRenderer extends DefaultTreeCellRenderer {
           /**
            *
            */
           private static final long serialVersionUID = 3892593039200536416L;
           private FileSystemView fileView;

           public CustomTreeCellRenderer() {
            fileView = Test.getFileView();
           }

           public Component getTreeCellRendererComponent(JTree tree, Object value,
             boolean selected, boolean expanded, boolean leaf, int row,
             boolean hasFocus) {
            super.getTreeCellRendererComponent(tree, value, selected, expanded,
              leaf, row, hasFocus);
            File file = (File) value;
            setIcon(fileView.getSystemIcon(file));
            setText(fileView.getSystemDisplayName(file));
            return this;
           }
          }

          posted on 2007-12-21 20:56 so true 閱讀(3721) 評論(1)  編輯  收藏 所屬分類: Java

          評論

          # re: JTree學習筆記!  回復  更多評論   

          好好學習天天向上
          2010-02-10 22:44 | bb
          主站蜘蛛池模板: 扬州市| 同德县| 胶南市| 榆林市| 抚顺市| 新密市| 洛浦县| 扎赉特旗| 修武县| 温宿县| 满城县| 福建省| 磐安县| 井冈山市| 尉氏县| 灵石县| 苗栗市| 河池市| 静安区| 前郭尔| 拉孜县| 金坛市| 叶城县| 登封市| 竹北市| 磐安县| 措勤县| 海安县| 水城县| 当涂县| 清镇市| 玉田县| 民权县| 淳化县| 启东市| 晋江市| 西林县| 和平县| 龙门县| 方城县| 荆州市|