【问题标题】:Multi selections in subtrees of JTreeJTree子树中的多选
【发布时间】:2013-02-05 15:43:08
【问题描述】:

我有一棵有几个子树(类别)的树,我如何只允许在指定的子树中进行多选操作,例如:我可以在类别中多选节点,但如果我会尝试在其他节点中选择一个节点category 它将取消选择当前子树中的节点并选择一个新的。

【问题讨论】:

    标签: java swing jtree multi-select


    【解决方案1】:

    使用setSelectionModel更改JTree的默认选择模型

    提供您自己的 TreeSelectionModel 实现

    【讨论】:

      【解决方案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); 
      

      【讨论】:

      • TreeSelectionModel默认JTree模式为DISCONTIGUOUS_TREE_SELECTION
      • 虽然 TreeSelectionListener 可以工作,但我发现这不是那么健壮,因为您在设置选择后对其进行修复,而不是防止设置不正确的选择。
      • 没错,我的解决方案有点脏,但更容易实现,因为 TreeSelectionModel 相当复杂。这是一种权衡。
      猜你喜欢
      • 2019-05-28
      • 1970-01-01
      • 2011-10-22
      • 2020-07-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-13
      • 2016-03-16
      相关资源
      最近更新 更多