Restricting the addition of nodes of a JTree excep

2019-07-21 16:48发布

问题:

I have been trying a lot of approaches on how to limit my code on adding nodes only to the 1st level. This means that the user can only add nodes to the 1st level children of a JTree.

Adding a node in my program can be done in 2 ways 1. Add node button 2. Select > Right click > Add node (In here, I wanted to disable this behavior if it a non 1st level child is selected. It's a long shot though )

I need a validation that permits the addition of nodes in other levels. Thanks!

Here is the working code:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;

public class ProblemTree extends JFrame {

    private DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root");
    private DefaultTreeModel model = new DefaultTreeModel(root);
    private JTree tree = new JTree(model);
    private JButton addButton = new JButton("Add Node to 1st level only");

    public ProblemTree() {
        DefaultMutableTreeNode n1 = new DefaultMutableTreeNode(
                "1st level: Child 1");
        n1.add(new DefaultMutableTreeNode("2nd level: Child l"));
        DefaultMutableTreeNode n2 = new DefaultMutableTreeNode(
                "1st level: Child 2");
        n2.add(new DefaultMutableTreeNode("2nd level: Child 2"));
        DefaultMutableTreeNode n3 = new DefaultMutableTreeNode(
                "1st level: Child 3");
        n3.add(new DefaultMutableTreeNode("2nd level: Child 3"));

        root.add(n1);
        root.add(n2);
        root.add(n3);

        tree.setEditable(true);
        tree.setSelectionRow(0);
        tree.setRootVisible(true);
        tree.setShowsRootHandles(true);

        final JPopupMenu popupMenu = new JPopupMenu();
        JMenuItem runTask = new JMenuItem("New Node for 1st level only =( ");
        runTask.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) tree
                        .getLastSelectedPathComponent();
                if (selNode == null) {
                    return;
                }
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
                        "New Node");
                model.insertNodeInto(newNode, selNode, selNode.getChildCount());

                TreeNode[] nodes = model.getPathToRoot(newNode);
                TreePath path = new TreePath(nodes);
                tree.scrollPathToVisible(path);
                tree.setSelectionPath(path);
                tree.startEditingAtPath(path);
            }
        });
        popupMenu.add(runTask);
        tree.setComponentPopupMenu(popupMenu);

        JScrollPane scrollPane = new JScrollPane(tree);
        getContentPane().add(scrollPane, BorderLayout.CENTER);

        JPanel panel = new JPanel();

        addButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                DefaultMutableTreeNode selNode = (DefaultMutableTreeNode) tree
                        .getLastSelectedPathComponent();
                if (selNode == null) {
                    return;
                }
                DefaultMutableTreeNode newNode = new DefaultMutableTreeNode(
                        "New Node");
                model.insertNodeInto(newNode, selNode, selNode.getChildCount());

                TreeNode[] nodes = model.getPathToRoot(newNode);
                TreePath path = new TreePath(nodes);
                tree.scrollPathToVisible(path);
                tree.setSelectionPath(path);
                tree.startEditingAtPath(path);
            }
        });
        panel.add(addButton);

        getContentPane().add(panel, BorderLayout.SOUTH);
        setSize(700, 400);
        setVisible(true);
    }

    public static void main(String[] arg) {
        ProblemTree pt = new ProblemTree();
    }
}

回答1:

just replace

tree.setComponentPopupMenu(popupMenu); 

with:

tree.addMouseListener(new MouseAdapter() {
    @Override
        public void mousePressed(MouseEvent e) {
        if (SwingUtilities.isRightMouseButton(e)) {
            int row = tree.getClosestRowForLocation(e.getX(), e.getY());
            tree.setSelectionRow(row);
            if (tree.getSelectionPath().getPathCount() == 2) {
                popupMenu.show(e.getComponent(), e.getX(), e.getY());
            }
        }
    }
});

and to control your button add:

addButton.setEnabled(false);
tree.addTreeSelectionListener(new TreeSelectionListener() {
    @Override
    public void valueChanged(TreeSelectionEvent e) {
        addButton.setEnabled((tree.getSelectionPath().getPathCount() == 2));
    }
});