【问题标题】:JTree: Selecting all nodes programmaticallyJTree:以编程方式选择所有节点
【发布时间】:2011-11-12 01:45:30
【问题描述】:

我有一个 Jtree 和 2 个按钮来选择和取消选择所有节点。我做了这样的尝试:

selectAll = new JButton("Select all");
selectAll.addActionListener(new ActionListener (){
        @Override
        public void actionPerformed(ActionEvent e) {
                int row = 0;
                while (row < curvesTree.getRowCount())
                {
                    curvesTree.expandRow(row);
                    row++;
                }
            int entradasTree = curvesTree.getRowCount();
            for(int i=0; i<entradasTree; i++){
                TreePath path = curvesTree.getPathForRow(i);
                curvesTree.setSelectionPath(path);
            }
        }
    });

        unselectAll = new JButton("Unselect all");
        unselectAll.addActionListener(new ActionListener (){
            @Override
            public void actionPerformed(ActionEvent e) {
                curvesTree.clearSelection();
            }
        });

取消选择按钮似乎正在工作,但全选仅扩展 JTree 并选择最后一个节点。我认为每次以编程方式选择一个节点时,我都会取消选择前一个节点。

JTree 是这样配置的:

curvesTree = new JTree(rootNode);
curvesTree.setExpandsSelectedPaths(true);
curvesTree.getSelectionModel().setSelectionMode(TreeSelectionModel.
                  DISCONTIGUOUS_TREE_SELECTION);

【问题讨论】:

    标签: java swing select jtree unselect


    【解决方案1】:

    取消选择是因为您设置了新的选择路径而不是添加。在展开后的循环中,改为做

     curvesTree.addSelectionPath(...)
    

    编辑

    阅读 api 总是有启发性的,即使经过多年 ;-) 刚刚发现了一个更简单的方法,它将所有工作都交给了树:

    tree.setSelectionInterval(0, tree.getRowCount());
    

    【讨论】:

    • 很好,你是怎么... +1
    • 谢谢,找了半个上午的方法:)
    【解决方案2】:

    可以,例如:

    import java.awt.Dimension;
    import javax.swing.*;
    import javax.swing.event.*;
    import javax.swing.tree.*;
    
    public class TreeWithMultiDiscontiguousSelections {
    
        public static void main(String[] argv) {
            JTree tree = new JTree();
            tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
            int treeSelectedRows[] = {3, 1};
            tree.setSelectionRows(treeSelectedRows);
            TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
    
                @Override
                public void valueChanged(TreeSelectionEvent treeSelectionEvent) {
                    JTree treeSource = (JTree) treeSelectionEvent.getSource();
                    System.out.println("Min: " + treeSource.getMinSelectionRow());
                    System.out.println("Max: " + treeSource.getMaxSelectionRow());
                    System.out.println("Lead: " + treeSource.getLeadSelectionRow());
                    System.out.println("Row: " + treeSource.getSelectionRows()[0]);
                }
            };
            tree.addTreeSelectionListener(treeSelectionListener);
            JFrame frame = new JFrame("JTree With Multi-Discontiguous selection");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new JScrollPane(tree));
            frame.setPreferredSize(new Dimension(380, 320));
            frame.setLocation(150, 150);
            frame.pack();
            frame.setVisible(true);
        }
    
        private TreeWithMultiDiscontiguousSelections() {
        }
    }
    

    【讨论】:

      【解决方案3】:

      我想补充一下 kleopatra 的答案(基于我自己的成长烦恼)。

      在我的特定问题中,我需要在JTree 节点弹出菜单中添加一个“选择所有子项”菜单项。因此,此解决方案适用于选定节点的所有子节点。

      TreeNode selectedNode = tree.getSelectionPath().getLastPathComponent();
      // Expand tree from selected node...
      List<TreePath> paths = new ArrayList<TreePath>();
      determineTreePaths(selectedNode, paths); // Recursive method call...
      
      TreePath[] treePaths = new TreePath[paths.size()];
      Iterator<TreePath> iter = paths.iterator();
      
      for (int i = 0; iter.hasNext(); ++i)
      {
         treePaths[i] = iter.next();
      }
      
      if (paths.size() > 0)
      {
         TreePath firstElement = paths.get(0);
         setSelectionPath(firstElement);
         scrollPathToVisible(firstElement);
      }    
      

      需要determineTreePaths(selectedNode, paths) 递归调用来遍历从选定节点一直到叶节点的树。无论深度如何,此解决方案都有效(据我所知)。我不能说这是最有效的解决方案。任何有更好解决方案的人,请随时发布不同的解决方案或编辑此解决方案。

      方法实现如下:

      private void determineTreePaths(TreeNode currentNode, List<TreePath> paths)
      {
         paths.add(new TreePath(((DefaultTreeModel) getDefaultTreeModel()).getPathToRoot(currentNode));
      
         // Get all of my Children
         Enumeration<?> children = currentNode.children();
      
         // iterate over my children
         while (children.hasMoreElements())
         {
            TreeNode child = (TreeNode) children.nextElement();
            determineTreePaths(child, paths);
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-05-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-07
        • 2013-07-29
        • 1970-01-01
        相关资源
        最近更新 更多