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

Java jtree右键单击仅选择一个节点,java,swing,jtree,selected,right-click,Java,Swing,Jtree,Selected,Right Click,我有一个JTree,可以(ctrl)选择多个节点。 当我右键单击时,我会弹出一个窗口,在那里我可以选择“刷新”。 (本网站上还有其他问题解释如何做到这一点) 问题是,当我选择多个节点并右键单击时,只有我右键单击的节点被选中,其他节点被取消选中 我想选择例如3个节点(叶子),右键单击,选择“刷新”,然后仍然选择这3个节点 有什么建议吗?谢谢 例如: import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; impor

我有一个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();
    }

}
下一行

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

if (tree.isSelectionEmpty()) {
    tree.setSelectionPath(path);
}
下一行

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

if (tree.isSelectionEmpty()) {
    tree.setSelectionPath(path);
}

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

    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();
        }

    }

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

    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();
        }

    }

为了获得更好的帮助,请尽快发布一个简短的、可运行的、可编译的、仅关于JFrame和JTree的文章,其中添加了TreeSelectionListener、其选择模式、获取SelectedXXX的代码以及如何调用JPOppMenu以使其可见Show us代码!听起来您在右键单击时正在更改选择,但除非我看到一些代码,否则无法判断。我添加了代码。它在树中;删除tree.setSelectionPath(path)行不会解决问题吗?为了更好地帮助您,请尽快发布一个简短、可运行、可编译的、仅关于JFrame和JTree的文章,并添加TreeSelectionListener、其选择模式、获取SelectedXXX的代码以及如何调用JPOppMenu以使其可见Show us代码!听起来您在右键单击时正在更改选择,但除非我看到一些代码,否则无法判断。我添加了代码。它在树中;删除tree.setSelectionPath(path)行不会解决问题吗?或者,如果要确保右键单击时至少选择了一行,则只能在
tree.isSelectionEmpty()返回true时执行该行。@VGR好主意。将其添加到答案中。您可能希望确定右键单击的位置,查看该行是否已选中,如果已选中,请不要更改选择。当右键单击发生在所选行之外时,您可能希望首先选择该行。谢谢各位,我调整了示例,使其符合Robin所说的。我还不能发布,但我会尽快发布。(8小时noob限制)或者,如果要确保右键单击时至少选择了一行,则只能在
tree.isSelectionEmpty()
返回true时执行该行。@VGR好主意。将其添加到答案中。您可能希望确定右键单击的位置,查看该行是否已选中,如果已选中,请不要更改选择。当右键单击发生在所选行之外时,您可能希望首先选择该行。谢谢各位,我调整了示例,使其符合Robin所说的。我还不能发布,但我会尽快发布。(八小时限制)