当前位置: 首页 > 知识库问答 >
问题:

jtree右键单击仅选择一个节点

张丰
2023-03-14

我有一个JTree,我可以(ctrl)选择多个节点。当我右键点击时,我会弹出一个窗口,在那里我可以选择“刷新”。(本网站上还有其他问题解释如何做到这一点)

问题是,当我选择多个节点并右键单击时,只有右键单击的节点被选中,其他节点被取消选择。

例如,我想选择3个节点(叶),右键单击,选择刷新,仍然选择这3个节点。

有什么建议吗?谢谢。

例子:

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class JTreeMultiSelect extends JFrame{

    public JTreeMultiSelect() {
        super("Test");

        JTree myTree = new JTree();
        myTree.getSelectionModel()
                .setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
        // add MouseListener to tree
        MouseAdapter ma = new MouseAdapter() {
            private void myPopupEvent(MouseEvent e) {
                int x = e.getX();
                int y = e.getY();
                JTree tree = (JTree)e.getSource();
                TreePath path = tree.getPathForLocation(x, y);
                if (path == null)
                    return;

                tree.setSelectionPath(path);

                DefaultMutableTreeNode rightClickedNode =
                        (DefaultMutableTreeNode)path.getLastPathComponent();

                if(rightClickedNode.isLeaf()){
                    JPopupMenu popup = new JPopupMenu();
                    final JMenuItem refreshMenuItem = new JMenuItem("refresh");
                    refreshMenuItem.addActionListener(new ActionListener(){
                        @Override
                        public void actionPerformed(ActionEvent actionEvent) {
                            System.out.println("refresh!");
                        }
                    });
                    popup.add(refreshMenuItem);
                    popup.show(tree, x, y);
                }
            }
            public void mousePressed(MouseEvent e) {
                if (e.isPopupTrigger()) myPopupEvent(e);
            }
            public void mouseReleased(MouseEvent e) {
                if (e.isPopupTrigger()) myPopupEvent(e);
            }
        };

        myTree.addMouseListener(ma);

        JPanel myPanel = new JPanel();
        myPanel.add(myTree);
        this.add(myPanel);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setVisible(true);

    }

    public static void main(String[] args) {
        new JTreeMultiSelect();
    }

}

共有2个答案

须彭亮
2023-03-14

以下是评论中promise的工作示例:

    import javax.swing.*;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.TreePath;
    import javax.swing.tree.TreeSelectionModel;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;

    public class JTreeMultiSelect extends JFrame{

        public JTreeMultiSelect() {
            super("Test");

            JTree myTree = new JTree();
            myTree.getSelectionModel()
                    .setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
            // add MouseListener to tree
            MouseAdapter ma = new MouseAdapter() {
                private void myPopupEvent(MouseEvent e) {
                    int x = e.getX();
                    int y = e.getY();
                    JTree tree = (JTree)e.getSource();
                    TreePath path = tree.getPathForLocation(x, y);
                    if (path == null)
                        return;

                    DefaultMutableTreeNode rightClickedNode =
                            (DefaultMutableTreeNode)path.getLastPathComponent();

                    TreePath[] selectionPaths = tree.getSelectionPaths();

                    //check if node was selected
                    boolean isSelected = false;
                    if (selectionPaths != null) {
                        for (TreePath selectionPath : selectionPaths) {
                            if (selectionPath.equals(path)) {
                                isSelected = true;
                            }
                        }
                    }
                    //if clicked node was not selected, select it
                    if(!isSelected){
                        tree.setSelectionPath(path);
                    }

                    //todo : create custom JMenuItem that takes the selectionPaths as parameter
                    //       and do the action for each node (using getLastPathComponent)
                    if(rightClickedNode.isLeaf()){
                        JPopupMenu popup = new JPopupMenu();
                        final JMenuItem refreshMenuItem = new JMenuItem("refresh");
                        refreshMenuItem.addActionListener(new ActionListener(){
                            @Override
                            public void actionPerformed(ActionEvent actionEvent) {
                                System.out.println("refresh!");
                            }
                        });
                        popup.add(refreshMenuItem);
                        popup.show(tree, x, y);
                    }
                }
                public void mousePressed(MouseEvent e) {
                    if (e.isPopupTrigger()) myPopupEvent(e);
                }
                public void mouseReleased(MouseEvent e) {
                    if (e.isPopupTrigger()) myPopupEvent(e);
                }
            };

            myTree.addMouseListener(ma);

            JPanel myPanel = new JPanel();
            myPanel.add(myTree);
            this.add(myPanel);
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.pack();
            this.setVisible(true);

        }

        public static void main(String[] args) {
            new JTreeMultiSelect();
        }

    }
空正豪
2023-03-14

下面这一行

tree.setSelectionPath(path);

将树选择重置为单个项目。您可能希望删除此行以获得所需的行为,或者更好地将其放入一个条件中,以处理无选择的情况:

if (tree.isSelectionEmpty()) {
    tree.setSelectionPath(path);
}
 类似资料:
  • 我知道如何通过鼠标左键点击所选项目来获取项目。我可以使用。 但我需要用鼠标右键点击项目。显示与单击的项目相关的弹出菜单。我试过这个: 但如果用户用右键点击该项,则会出现问题。右键单击不选择项目。如何按事件坐标选择项目或如何解决此问题?主要我需要得到的对象是点击没有选择项目,如果可能的话。

  • 我正在使用Selenium webdriver。我无法从右键单击打开的选项中选择(例如第二个)选项。 在我当前的代码中,我可以右键单击webElement,但无法从右键单击后打开的列表中选择选项,因为它会自动消失。 因此,有了这段代码,我可以右键单击,但右键单击菜单会自动消失。我想从右键菜单中选择第二个选项。 请帮助!!!

  • 我设置了一个JPopupMenu,它将显示用户是否右键单击JList中的某个单元格,但现在必须先选择该单元格,才能显示JPopupMenu。我想知道如何在右键单击后选择该单元格,然后像现在一样显示JPopupMenu。当没有选择任何项目并且鼠标不在列表中的任何项目上时,我也会显示一个菜单。 代码:

  • 我从这里摘取了一些代码,允许通过单击行上的任何位置来选择JTree行。它在单行选择模式下工作良好。但是,我不确定如何修改它,以便处理多行选择。当用户进行多个选择(例如,在鼠标左键单击一行的同时按住shift或control按钮)时,我如何区分这种情况?

  • 我正在开发一个使用JTree的java应用程序。我想归档的是,当我点击一个已经被选中的节点时,它会被取消选中。 我目前的解决方案是向jtree添加鼠标侦听器和树选择侦听器。但问题是,valueChanged只有在选择发生更改时才会被调用(而不是在两次选择同一节点时)。为了解决这个问题,我添加了一个布尔值,它指示是否第一次单击了节点,然后我在MouseRelease函数中处理取消选择。这是可行的,但

  • 问题内容: 我们正在IntelliJ中创建一个新项目,并且一定有问题,因为当我们右键单击目录时,选择“ 新建” ,然后获得上下文菜单,则不会显示基于Java的选项。当前获得诸如文件,一些HTML选项,XML选项之类的东西。 到目前为止,我们已经假设这是在Project / Module配置中尚未正确配置的东西。我们正在讨论的新模块是多模块项目的一部分。我们使用Maven网络原型创建了它。 对配置项