2013-02-05 35 views
1

我有一棵樹,有幾個子樹(類別),我如何允許只在指定的子樹中執行多重選擇操作,例如:我可以在類別中選擇多個節點,但是如果我嘗試要選擇其他類別的節點,將取消選擇當前子樹中的節點並選擇一個新節點。JTree的子樹中的多重選擇

回答

2

沒有必要實施TreeSelectionModel的,它足以實現與默認模型TreeSelectionListener。這裏有一個半工作示例,需要更多的調整,以完美的工作,但它說明了一個道理:

JFrame f = new JFrame("JTree test"); 
    f.setSize(300, 300); 
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    JTree t = new JTree(); 
    DefaultTreeModel model = (DefaultTreeModel) t.getModel(); 
    final TreeSelectionModel selectionModel = t.getSelectionModel(); 

    selectionModel.setSelectionMode(TreeSelectionModel.CONTIGUOUS_TREE_SELECTION); 
    selectionModel.addTreeSelectionListener(new TreeSelectionListener() { 
     @Override 
     public void valueChanged(TreeSelectionEvent e) { 
      // detect additive selections 
      if (e.isAddedPath()) { 
       TreePath selection = e.getPath(); 
       DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) selection 
         .getLastPathComponent(); 

       // a contrived way to detect selection of items within a category 
       if (((String) selectedNode.getUserObject()) 
         .startsWith("Item")) { 
        // get the new selection's category node 
        DefaultMutableTreeNode category = (DefaultMutableTreeNode) selection 
          .getParentPath().getLastPathComponent(); 

        // deselect everything outside that category 
        ArrayList<TreePath> deselectList = new ArrayList<TreePath>(); 
        for (TreePath path : selectionModel.getSelectionPaths()) { 
         if (!category.equals(path.getParentPath() 
           .getLastPathComponent())) { 
          deselectList.add(path); 
         } 
        } 
        selectionModel.removeSelectionPaths(deselectList 
          .toArray(new TreePath[deselectList.size()])); 
       } else { 
        // completely prevent selection of categories 
        selectionModel.removeSelectionPath(selection); 
       } 
      } 
     } 
    }); 

    DefaultMutableTreeNode root = new DefaultMutableTreeNode(); 
    DefaultMutableTreeNode category1 = new DefaultMutableTreeNode("Category 1"); 
    DefaultMutableTreeNode category2 = new DefaultMutableTreeNode("Category 2"); 
    DefaultMutableTreeNode item1 = new DefaultMutableTreeNode("Item 1"); 
    DefaultMutableTreeNode item2 = new DefaultMutableTreeNode("Item 2"); 
    DefaultMutableTreeNode item3 = new DefaultMutableTreeNode("Item 3"); 
    DefaultMutableTreeNode item4 = new DefaultMutableTreeNode("Item 4"); 

    category1.add(item1); 
    category1.add(item2); 
    category2.add(item3); 
    category2.add(item4); 

    root.add(category1); 
    root.add(category2); 

    t.setRootVisible(false); 
    model.setRoot(root); 

    f.getContentPane().add(new JScrollPane(t)); 
    f.setVisible(true); 
+0

默認'的TreeSelectionModel'模式'JTree'是'DISCONTIGUOUS_TREE_SELECTION'。 – trashgod

+0

儘管TreeSelectionListener可以正常工作,但我發現這並不穩健,因爲您在設置後正在修改選擇,而不是防止設置不正確的選擇。 –

+0

的確,我的解決方案有點髒,但實現起來更容易,因爲TreeSelectionModel相當複雜。這是一個權衡。 – jblazevic