繁体   English   中英

在特定行的JTree中手动插入节点

[英]Manual Insertion of node in JTree on specific row

我正在使用docs.oracle.com教程中的DynamicTree和DynamicTreeDemo类。 给定的示例允许在所选节点上动态添加子节点。

我已经修改了

DefaultMutableTreeNode addObject(Object child) 

更改TreePath的函数。 那就是我已经修复了树路径,因此每当我单击“添加”按钮时,它只会将子节点添加到该路径。

    Object[] o = { new DefaultMutableTreeNode("Root Node"), new DefaultMutableTreeNode("Parent 2"),
            new DefaultMutableTreeNode("Child 2") };

    parentPath = new TreePath(o);

但是修改后,添加按钮不起作用。 如何解决此问题,以便可以通过更改代码中的路径来添加节点?

import java.awt.GridLayout;
import java.awt.Toolkit;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.MutableTreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import javax.swing.event.TreeModelEvent;
import javax.swing.event.TreeModelListener;

public class DynamicTree extends JPanel {
protected DefaultMutableTreeNode rootNode;
protected DefaultTreeModel treeModel;
protected JTree tree;
private Toolkit toolkit = Toolkit.getDefaultToolkit();

public DynamicTree() {
    super(new GridLayout(1, 0));

    rootNode = new DefaultMutableTreeNode("Root Node");
    treeModel = new DefaultTreeModel(rootNode);
    treeModel.addTreeModelListener(new MyTreeModelListener());
    tree = new JTree(treeModel);
    tree.setEditable(true);
    tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
    tree.setShowsRootHandles(true);

    JScrollPane scrollPane = new JScrollPane(tree);
    add(scrollPane);
}

/** Remove all nodes except the root node. */
public void clear() {
    rootNode.removeAllChildren();
    treeModel.reload();
}

/** Remove the currently selected node. */
public void removeCurrentNode() {
    TreePath currentSelection = tree.getSelectionPath();
    if (currentSelection != null) {
        DefaultMutableTreeNode currentNode = (DefaultMutableTreeNode) (currentSelection.getLastPathComponent());
        MutableTreeNode parent = (MutableTreeNode) (currentNode.getParent());
        if (parent != null) {
            treeModel.removeNodeFromParent(currentNode);
            return;
        }
    }

    // Either there was no selection, or the root was selected.
    toolkit.beep();
}

/** Add child to the currently selected node. */
public DefaultMutableTreeNode addObject(Object child) {
    DefaultMutableTreeNode parentNode = null;
    TreePath parentPath = tree.getSelectionPath();

    //////////////////////////// Modification for fixing place /////////////    

    Object[] o = { new DefaultMutableTreeNode("Root Node"), new DefaultMutableTreeNode("Parent 2"),
            new DefaultMutableTreeNode("Child 2") };

    parentPath = new TreePath(o);

    //////////////////////////// end of modification///////////////////////


    if (parentPath == null) {
        parentNode = rootNode;
    } else {
        parentNode = (DefaultMutableTreeNode) (parentPath.getLastPathComponent());
    }

    return addObject(parentNode, child, true);
}

public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child) {
    return addObject(parent, child, false);
}

public DefaultMutableTreeNode addObject(DefaultMutableTreeNode parent, Object child, boolean shouldBeVisible) {
    DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(child);

    if (parent == null) {
        parent = rootNode;
    }

    // It is key to invoke this on the TreeModel, and NOT DefaultMutableTreeNode
    treeModel.insertNodeInto(childNode, parent, parent.getChildCount());

    // Make sure the user can see the lovely new node.
    if (shouldBeVisible) {
        tree.scrollPathToVisible(new TreePath(childNode.getPath()));
    }
    return childNode;
}

class MyTreeModelListener implements TreeModelListener {
    public void treeNodesChanged(TreeModelEvent e) {
        DefaultMutableTreeNode node;
        node = (DefaultMutableTreeNode) (e.getTreePath().getLastPathComponent());

        /*
         * If the event lists children, then the changed node is the child of the node
         * we've already gotten. Otherwise, the changed node and the specified node are
         * the same.
         */

        int index = e.getChildIndices()[0];
        node = (DefaultMutableTreeNode) (node.getChildAt(index));

        System.out.println("The user has finished editing the node.");
        System.out.println("New value: " + node.getUserObject());
    }

    public void treeNodesInserted(TreeModelEvent e) {
    }

    public void treeNodesRemoved(TreeModelEvent e) {
    }

    public void treeStructureChanged(TreeModelEvent e) {
    }
}
}





import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.tree.DefaultMutableTreeNode;

public class DynamicTreeDemo extends JPanel implements ActionListener {
private int newNodeSuffix = 1;
private static String ADD_COMMAND = "add";
private static String REMOVE_COMMAND = "remove";
private static String CLEAR_COMMAND = "clear";

private DynamicTree treePanel;

public DynamicTreeDemo() {
    super(new BorderLayout());

    // Create the components.
    treePanel = new DynamicTree();
    populateTree(treePanel);

    JButton addButton = new JButton("Add");
    addButton.setActionCommand(ADD_COMMAND);
    addButton.addActionListener(this);

    JButton removeButton = new JButton("Remove");
    removeButton.setActionCommand(REMOVE_COMMAND);
    removeButton.addActionListener(this);

    JButton clearButton = new JButton("Clear");
    clearButton.setActionCommand(CLEAR_COMMAND);
    clearButton.addActionListener(this);

    // Lay everything out.
    treePanel.setPreferredSize(new Dimension(300, 150));
    add(treePanel, BorderLayout.CENTER);

    JPanel panel = new JPanel(new GridLayout(0, 3));
    panel.add(addButton);
    panel.add(removeButton);
    panel.add(clearButton);
    add(panel, BorderLayout.SOUTH);
}

public void populateTree(DynamicTree treePanel) {
    String p1Name = new String("Parent 1");
    String p2Name = new String("Parent 2");
    String c1Name = new String("Child 1");
    String c2Name = new String("Child 2");

    DefaultMutableTreeNode p1, p2;

    p1 = treePanel.addObject(null, p1Name);
    p2 = treePanel.addObject(null, p2Name);

    treePanel.addObject(p1, c1Name);
    treePanel.addObject(p1, c2Name);

    treePanel.addObject(p2, c1Name);
    treePanel.addObject(p2, c2Name);
}

public void actionPerformed(ActionEvent e) {
    String command = e.getActionCommand();

    if (ADD_COMMAND.equals(command)) {
        // Add button clicked
        treePanel.addObject("New Node " + newNodeSuffix++);
    } else if (REMOVE_COMMAND.equals(command)) {
        // Remove button clicked
        treePanel.removeCurrentNode();
    } else if (CLEAR_COMMAND.equals(command)) {
        // Clear button clicked.
        treePanel.clear();
    }
}

/**
 * Create the GUI and show it. For thread safety, this method should be invoked
 * from the event-dispatching thread.
 */
private static void createAndShowGUI() {
    // Create and set up the window.
    JFrame frame = new JFrame("DynamicTreeDemo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    // Create and set up the content pane.
    DynamicTreeDemo newContentPane = new DynamicTreeDemo();
    newContentPane.setOpaque(true); // content panes must be opaque
    frame.setContentPane(newContentPane);

    // Display the window.
    frame.pack();
    frame.setVisible(true);
}

public static void main(String[] args) {
    // Schedule a job for the event-dispatching thread:
    // creating and showing this application's GUI.
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            createAndShowGUI();
        }
    });
}
}

您所做的修改是不正确的,因为通过创建一些与现有节点同名的新DefaultMutableTreeNode ,新TreePath将不是同一TreePath对象。 他们的参考文献不同。 然后,在TreeModel找不到您正在创建的新路径,并且您看到的结果什么都没有发生。

您应该从TreeModel本身获得用于插入新节点的路径。 例如,如果要将新的子代添加到“子代2” ,则可以像这样获得其引用:

// ////////////////////////// Modification for fixing place // /////////////

Object[] o = { rootNode.getLastLeaf() }; // For you testing purposes 
                                         // this will return the Child 2" reference, 
                                         // next time it will return "New Node 2" and so on.

parentPath = new TreePath(o);

// ////////////////////////// end of modification///////////////////////

如果你想在一个特定的位置添加一个新的节点,你应该得到的到现有节点的引用TreeModel并不是凭空的一个新的TreeNode ,其目前不存在于TreeModel

希望这可以帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM