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

JTree通过单击行上的任意位置选择节点

於和志
2023-03-14

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

import java.awt.Rectangle;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeNode;


@SuppressWarnings("serial")
public class NavTree extends JTree {

    private boolean                 fWholeRowSelectionEnabled;
    private MouseListener           fRowSelectionListener;
    final NavTree                   fThis;

    public NavTree(TreeNode rootNode) {
        super(rootNode);
        fThis = this;
        init();
    }
    public NavTree() {
        fThis = this;
        init();
    }

    private void init() {
        //setCellRenderer(new NavTreeCellRenderer());
        fRowSelectionListener = new MouseAdapter() {

            public void mousePressed(MouseEvent e) {
                if (SwingUtilities.isLeftMouseButton(e)) {
                    int closestRow = fThis.getClosestRowForLocation(
                            e.getX(), e.getY());
                    Rectangle closestRowBounds = fThis.getRowBounds(closestRow);
                    if(e.getY() >= closestRowBounds.getY() && 
                            e.getY() < closestRowBounds.getY() + 
                            closestRowBounds.getHeight()) {
                        if(e.getX() > closestRowBounds.getX() && 
                                closestRow < fThis.getRowCount()){

                                                    fThis.setSelectionRow(closestRow);
                                                }

                    } else
                        fThis.setSelectionRow(-1);
                }
            }

        };
        setWholeRowSelectionEnabled(true);
    }

    public void setWholeRowSelectionEnabled(boolean wholeRowSelectionEnabled) {
        fWholeRowSelectionEnabled = wholeRowSelectionEnabled;
        if (fWholeRowSelectionEnabled)
            addMouseListener(fRowSelectionListener);
        else
            removeMouseListener(fRowSelectionListener);
    }

    public boolean isWholeRowSelectionEnabled() {
        return fWholeRowSelectionEnabled;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
        root.add(new DefaultMutableTreeNode("Child 1"));
        root.add(new DefaultMutableTreeNode("Child 2"));
        root.add(new DefaultMutableTreeNode("Child 3"));
        NavTree tree = new NavTree(root);
        frame.add(tree);
        frame.setSize(200, 300);
        frame.setVisible(true);
    }
}

共有2个答案

祁杰
2023-03-14

ps:监听器注册包含一个bug

public void setWholeRowSelectionEnabled(boolean wholeRowSelectionEnabled) {
    fWholeRowSelectionEnabled = wholeRowSelectionEnabled;
    if (fWholeRowSelectionEnabled)
        addMouseListener(fRowSelectionListener);
    else
        removeMouseListener(fRowSelectionListener);
}

将属性WholeRowSelectionEnabled设置为True应只注册侦听器一次。如果属性多次设置为true,则代码将一次又一次地添加侦听器。我的意思是属性设置器应该是幂等的。

快速修复可以是首先删除它,然后在启用时添加它

public void setWholeRowSelectionEnabled(boolean wholeRowSelectionEnabled) {
    removeMouseListener(fRowSelectionListener);
    fWholeRowSelectionEnabled = wholeRowSelectionEnabled;
    if (fWholeRowSelectionEnabled)
        addMouseListener(fRowSelectionListener);
}
澹台锐
2023-03-14

使用mouseevent的修饰符键信息。有关详细信息,请参阅MouseEvent#GetModifierSex

 类似资料:
  • 我有一个JTree,我可以(ctrl)选择多个节点。当我右键点击时,我会弹出一个窗口,在那里我可以选择“刷新”。(本网站上还有其他问题解释如何做到这一点) 问题是,当我选择多个节点并右键单击时,只有右键单击的节点被选中,其他节点被取消选择。 例如,我想选择3个节点(叶),右键单击,选择刷新,仍然选择这3个节点。 有什么建议吗?谢谢。 例子:

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

  • 我是r-plotly的新手,我正在试图弄清楚如何处理不在数据上的点击。似乎使用我可以从数据中获取点上的事件,但到目前为止,我还没有弄清楚如何对不接近数据但仅在绘图白色部分的单击执行此操作。 来自绘图的闪亮点击事件可以做到这一点,我只需要得到点击的x和y。我想要类似的,但情节要详细。 我是否可以将单击事件指定为来自plotly plot上的任意位置,而不仅仅是数据? 编辑:令人惊讶的是,这在plot

  • 问题内容: 这是很常见的事情,例如,如果您在此处单击stackoverflow上的收件箱。我会打电话给那个对话框或任何被打开的 东西 。 现在我知道有两种方法可以解决这个问题, 你创建一个无形的覆盖,但只有用户打开该元素具有更大的zIndex以及您关闭 的事情 上叠加通过点击 点击文档事件,而你检查在点击你是否点击你的事还是境外,在这种情况下,你闭上你 的事 。 无论哪种情况,我都希望使用添加/删

  • 我正在尝试在plotly中实现“单击任意位置”功能,以便在用户单击plotly图表的任意位置时获得坐标。当前的“官方”plotly功能仅在用户单击打印数据点时起作用,但我想注册单击,例如在背景白色画布上。 plotly中闪亮的点击事件可以做到这一点,但令人惊讶的是,plotly中似乎还不存在这种情况。 我做了一些研究,发现下面的代码笔实现非常接近:https://codepen.io/tim-lo

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