首页 文章

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

提问于
浏览
1

我有代码taken from here,它允许通过单击行上的任何位置来选择JTree行 . 它在单行选择模式下工作正常 . 但是,我不知道如何修改它以处理多行选择 . 如何区分用户进行多项选择时的情况(例如,通过在按住鼠标左键的同时按住shift或控制按钮)?

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 回答

  • 0

    使用 MouseEvent 的修饰键信息 . 有关更多信息,请参阅MouseEvent#getModifiersEx

  • 3

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

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

    将属性 wholeRowSelectionEnabled 设置为 true 应该只注册一次侦听器 . 如果属性多次设置为 true ,您的代码将一次又一次地添加侦听器 . 我的意思是属性设置器应该是idempotent .

    一个quickfix可能是先删除它,如果启用则添加它

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

相关问题