zeyuphoenix

          愿我愛的人快樂,愿愛我的人快樂,為了這些,我愿意不快樂.

          JTree--樹(基本使用)

          JTree也是一個分層顯示數據的組件,它在Swing里復雜度算是中等,涉及的類不是很多,也沒有復雜的UI,所以單獨對一個樹來說,構造和渲染都不難,對于樹的操作比較麻煩的是拖拽和與其他組件數據交互.

          對于JTree有幾個比較重要的類和接口: TreeMode是一個接口,用來構建樹的模型,實現這個接口之后我們可以把一些比較另類的組件抽象成一棵樹,TreeTable就是這個原理實現的;TreeNode是一個接口,代表樹的節點,DefaultMutableTreeNode是該接口的一個實現,我們一般構建樹使用它就可以了,當然也可以繼承它添加新的功能,或者實現TreeNode把節點變成其它組件; TreePath是一個類,負責節點到根的路徑,一般不需要我們來修改; TreeSelectionModel是一個接口,表示樹選擇組件的當前狀態,只是使用皆可以了,一般除非做很大的改動,否則不需要修改這個類;還有就是TreeCellRendererTreeCellEditor,它們是樹的渲染器,實現特殊效果都需要實現它們;還有就是TreeUI,樹的UI比較死板,很少需要修改.

          由上面類和接口可以,樹還是一個不是很復雜的組件的,除了基本使用外,我們一般會用到的也就是對Cell進行渲染,替換樹的節點圖片,或者給節點加個CheckBox這些了.

          先看樹的簡單使用,Sun官方給我們提供了例子:

          這個例子只是簡單的構建一棵樹:

                 // 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、



          removeNodeFromParent、nodeChanged等方法就可以實現了,但是如果是我們自己實現的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官方提供的:

          首先看它的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的使用,只不過為了邏輯和應用,做的更復雜.

          posted on 2010-04-20 22:36 zeyuphoenix 閱讀(9813) 評論(0)  編輯  收藏 所屬分類: JTree的使用

          導航

          <2010年4月>
          28293031123
          45678910
          11121314151617
          18192021222324
          2526272829301
          2345678

          統計

          常用鏈接

          留言簿(52)

          隨筆分類

          隨筆檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 朝阳区| 鸡东县| 凤台县| 南江县| 六枝特区| 北海市| 昭通市| 迭部县| 大冶市| 乐东| 香港| 墨竹工卡县| 北安市| 白水县| 永登县| 监利县| 绥宁县| 丹棱县| 进贤县| 鸡西市| 聂拉木县| 商水县| 蒙自县| 祁门县| 南京市| 拉萨市| 淄博市| 重庆市| 同江市| 郯城县| 志丹县| 多伦县| 太保市| 衡东县| 雅江县| 葫芦岛市| 永昌县| 东莞市| 宁强县| 巴南区| 贡觉县|